X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fcwindowgui.C;h=22e977bdf3b3ef28e973f726f8bb748c386a5229;hp=8cf018446e68c13b330edcd77ff78b673522d561;hb=98e035865979cda9805a58a85d52f8d70a7ec54e;hpb=253199c03ee8a0247e1ee7f9ba063c320f705aea diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index 8cf01844..22e977bd 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -77,15 +77,11 @@ static int total_zooms = sizeof(my_zoom_table) / sizeof(double); CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow) : BC_Window(_(PROGRAM_NAME ": Compositor"), - mwindow->session->cwindow_x, - mwindow->session->cwindow_y, - mwindow->session->cwindow_w, - mwindow->session->cwindow_h, - 100, - 100, - 1, - 1, - 1, + mwindow->session->cwindow_x, + mwindow->session->cwindow_y, + mwindow->session->cwindow_w, + mwindow->session->cwindow_h, + xS(100), yS(100), 1, 1, 1, BC_WindowBase::get_resources()->bg_color, mwindow->get_cwindow_display()) { @@ -119,15 +115,17 @@ CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow) CWindowGUI::~CWindowGUI() { - if(tool_panel) delete tool_panel; - delete meters; - delete composite_panel; - delete canvas; - delete transport; - delete edit_panel; - delete zoom_panel; + cwindow->stop_playback(1); + if( tool_panel ) delete tool_panel; + delete meters; + delete composite_panel; + delete canvas; + delete transport; + delete edit_panel; + delete zoom_panel; delete active; delete inactive; + delete focus_frame; delete orig_mask_keyframe; } @@ -138,6 +136,7 @@ void CWindowGUI::create_objects() active = new BC_Pixmap(this, mwindow->theme->get_image("cwindow_active")); inactive = new BC_Pixmap(this, mwindow->theme->get_image("cwindow_inactive")); + focus_frame = new VFramePng(mwindow->theme->get_image_data("cwindow_focus.png")); mwindow->theme->get_cwindow_sizes(this, mwindow->session->cwindow_controls); mwindow->theme->draw_cwindow_bg(this); @@ -175,11 +174,11 @@ void CWindowGUI::create_objects() timebar->create_objects(); #ifdef USE_SLIDER - add_subwindow(slider = new CWindowSlider(mwindow, - cwindow, + add_subwindow(slider = new CWindowSlider(mwindow, + cwindow, mwindow->theme->cslider_x, - mwindow->theme->cslider_y, - mwindow->theme->cslider_w)); + mwindow->theme->cslider_y, + mwindow->theme->cslider_w)); #endif transport = new CWindowTransport(mwindow, @@ -209,12 +208,6 @@ void CWindowGUI::create_objects() if( !mwindow->edl->session->cwindow_scrollbars ) zoom_panel->set_text(auto_zoom); -// destination = new CWindowDestination(mwindow, -// this, -// mwindow->theme->cdest_x, -// mwindow->theme->cdest_y); -// destination->create_objects(); - // Must create after meter panel tool_panel = new CWindowTool(mwindow, this); tool_panel->Thread::start(); @@ -245,18 +238,15 @@ int CWindowGUI::resize_event(int w, int h) composite_panel->reposition_buttons(mwindow->theme->ccomposite_x, mwindow->theme->ccomposite_y, mwindow->theme->ccomposite_h); - canvas->reposition_window(mwindow->edl, - mwindow->theme->ccanvas_x, - mwindow->theme->ccanvas_y, - mwindow->theme->ccanvas_w, - mwindow->theme->ccanvas_h); + canvas->set_zoom(mwindow->edl, canvas->get_zoom()); + update_canvas(); timebar->resize_event(); #ifdef USE_SLIDER - slider->reposition_window(mwindow->theme->cslider_x, - mwindow->theme->cslider_y, - mwindow->theme->cslider_w); + slider->reposition_window(mwindow->theme->cslider_x, + mwindow->theme->cslider_y, + mwindow->theme->cslider_w); // Recalibrate pointer motion range slider->set_position(); #endif @@ -315,36 +305,35 @@ int CWindowGUI::button_press_event() return transport->frame_reverse_play->handle_event(); } } - if(canvas->get_canvas()) + if( canvas->get_canvas() ) return canvas->button_press_event_base(canvas->get_canvas()); return 0; } int CWindowGUI::cursor_leave_event() { - if(canvas->get_canvas()) + if( canvas->get_canvas() ) return canvas->cursor_leave_event_base(canvas->get_canvas()); return 0; } int CWindowGUI::cursor_enter_event() { - if(canvas->get_canvas()) + if( canvas->get_canvas() ) return canvas->cursor_enter_event_base(canvas->get_canvas()); return 0; } int CWindowGUI::button_release_event() { - if(canvas->get_canvas()) + if( canvas->get_canvas() ) return canvas->button_release_event(); return 0; } int CWindowGUI::cursor_motion_event() { - if(canvas->get_canvas()) - { + if( canvas->get_canvas() ) { canvas->get_canvas()->unhide_cursor(); return canvas->cursor_motion_event(); } @@ -360,14 +349,12 @@ int CWindowGUI::cursor_motion_event() void CWindowGUI::draw_status(int flush) { if( (canvas->get_canvas() && canvas->get_canvas()->get_video_on()) || - canvas->is_processing ) - { + canvas->is_processing ) { draw_pixmap(active, mwindow->theme->cstatus_x, mwindow->theme->cstatus_y); } - else - { + else { draw_pixmap(inactive, mwindow->theme->cstatus_x, mwindow->theme->cstatus_y); @@ -383,43 +370,20 @@ void CWindowGUI::draw_status(int flush) flush); } -float CWindowGUI::get_auto_zoom() -{ - float conformed_w, conformed_h; - mwindow->edl->calculate_conformed_dimensions(0, conformed_w, conformed_h); - float zoom_x = canvas->w / conformed_w; - float zoom_y = canvas->h / conformed_h; - return zoom_x < zoom_y ? zoom_x : zoom_y; -} - -void CWindowGUI::zoom_canvas(double value, int update_menu) +void CWindowGUI::update_canvas(int redraw) { - float x = 0, y = 0; - float zoom = !value ? get_auto_zoom() : value; - EDL *edl = mwindow->edl; - edl->session->cwindow_scrollbars = !value ? 0 : 1; - if( value ) { - float cx = 0.5f * canvas->w; x = cx; - float cy = 0.5f * canvas->h; y = cy; - canvas->canvas_to_output(edl, 0, x, y); - canvas->update_zoom(0, 0, zoom); - float zoom_x, zoom_y, conformed_w, conformed_h; - canvas->get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h); - x -= cx / zoom_x; - y -= cy / zoom_y; - - } - canvas->update_zoom((int)(x+0.5), (int)(y+0.5), zoom); - - if( update_menu ) - zoom_panel->update(value); - if( mwindow->edl->session->cwindow_operation == CWINDOW_ZOOM ) + float zoom = canvas->get_zoom(); + zoom_panel->update(zoom); + if( mwindow->edl->session->cwindow_operation == CWINDOW_ZOOM ) { + if( !zoom ) zoom = canvas->get_auto_zoom(mwindow->edl); composite_panel->cpanel_zoom->update(zoom); - + } + canvas->update_scrollbars(mwindow->edl, 0); canvas->reposition_window(mwindow->edl, mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y, mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h); - canvas->draw_refresh(); + if( redraw ) + canvas->refresh(0); } void CWindowGUI::set_operation(int value) @@ -443,7 +407,7 @@ void CWindowGUI::set_operation(int value) edit_panel->update(); tool_panel->start_tool(value); - canvas->draw_refresh(); + canvas->refresh(0); } void CWindowGUI::update_tool() @@ -478,13 +442,13 @@ int CWindowGUI::keypress_event() keyboard_zoomout(); result = 1; break; - case 'f': - unlock_window(); - if(mwindow->session->cwindow_fullscreen) - canvas->stop_fullscreen(); - else - canvas->start_fullscreen(); - lock_window("CWindowGUI::keypress_event 1"); + case 'f': { + int on = canvas->get_fullscreen() ? 0 : 1; + canvas->set_fullscreen(on, 1); + result = 1; + break; } + case ESC: + canvas->set_fullscreen(0, 1); result = 1; break; case 'x': @@ -504,13 +468,6 @@ int CWindowGUI::keypress_event() lock_window("CWindowGUI::keypress_event 3"); result = 1; break; - case ESC: - unlock_window(); - if(mwindow->session->cwindow_fullscreen) - canvas->stop_fullscreen(); - lock_window("CWindowGUI::keypress_event 4"); - result = 1; - break; case LEFT: if( !ctrl_down() ) { int alt_down = this->alt_down(); @@ -524,7 +481,7 @@ int CWindowGUI::keypress_event() mwindow->move_left(); mwindow->gui->unlock_window(); lock_window("CWindowGUI::keypress_event 6"); - result = 1; + result = 1; } break; @@ -648,37 +605,28 @@ void CWindowGUI::reset_affected() void CWindowGUI::keyboard_zoomin() { -// if(mwindow->edl->session->cwindow_scrollbars) -// { - zoom_panel->zoom_tumbler->handle_up_event(); -// } -// else -// { -// } + zoom_panel->zoom_tumbler->handle_up_event(); } void CWindowGUI::keyboard_zoomout() { -// if(mwindow->edl->session->cwindow_scrollbars) -// { - zoom_panel->zoom_tumbler->handle_down_event(); -// } -// else -// { -// } + zoom_panel->zoom_tumbler->handle_down_event(); } -void CWindowGUI::sync_parameters(int change_type, int tool, int overlay) +void CWindowGUI::sync_parameters(int change_type, int redraw, int overlay) { - if( tool ) update_tool(); + if( redraw ) { + update_tool(); + canvas->refresh(1); + } if( change_type < 0 && !overlay ) return; unlock_window(); if( change_type >= 0 ) { mwindow->restart_brender(); - mwindow->sync_parameters(CHANGE_PARAMS); + mwindow->sync_parameters(change_type); } if( overlay ) { - mwindow->gui->lock_window("CWindow::camera_keyframe"); + mwindow->gui->lock_window("CWindowGUI::sync_parameters"); mwindow->gui->draw_overlays(1); mwindow->gui->unlock_window(); } @@ -687,40 +635,37 @@ void CWindowGUI::sync_parameters(int change_type, int tool, int overlay) void CWindowGUI::drag_motion() { - if(get_hidden()) return; + if( get_hidden() ) return; - if(mwindow->session->current_operation != DRAG_ASSET && + if( mwindow->session->current_operation != DRAG_ASSET && mwindow->session->current_operation != DRAG_VTRANSITION && - mwindow->session->current_operation != DRAG_VEFFECT) return; + mwindow->session->current_operation != DRAG_VEFFECT ) return; int need_highlight = cursor_above() && get_cursor_over_window(); if( highlighted == need_highlight ) return; highlighted = need_highlight; - canvas->draw_refresh(); + canvas->refresh(1); } int CWindowGUI::drag_stop() { int result = 0; - if(get_hidden()) return 0; + if( get_hidden() ) return 0; if( !highlighted ) return 0; if( mwindow->session->current_operation != DRAG_ASSET && mwindow->session->current_operation != DRAG_VTRANSITION && mwindow->session->current_operation != DRAG_VEFFECT) return 0; highlighted = 0; - canvas->draw_refresh(); + canvas->refresh(1); result = 1; - if(mwindow->session->current_operation == DRAG_ASSET) - { - if(mwindow->session->drag_assets->total || - mwindow->session->drag_clips->total) - { + if( mwindow->session->current_operation == DRAG_ASSET ) { + if( mwindow->session->drag_assets->total || + mwindow->session->drag_clips->total ) { mwindow->gui->lock_window("CWindowGUI::drag_stop 1"); mwindow->undo->update_undo_before(_("insert assets"), 0); } - if(mwindow->session->drag_assets->total) - { + if( mwindow->session->drag_assets->total ) { mwindow->clear(0); mwindow->load_assets(mwindow->session->drag_assets, mwindow->edl->local_session->get_selectionstart(), @@ -733,8 +678,7 @@ int CWindowGUI::drag_stop() 0); // overwrite } - if(mwindow->session->drag_clips->total) - { + if( mwindow->session->drag_clips->total ) { mwindow->clear(0); mwindow->paste_edls(mwindow->session->drag_clips, LOADMODE_PASTE, @@ -746,9 +690,8 @@ int CWindowGUI::drag_stop() 0); // overwrite } - if(mwindow->session->drag_assets->total || - mwindow->session->drag_clips->total) - { + if( mwindow->session->drag_assets->total || + mwindow->session->drag_clips->total ) { mwindow->save_backup(); mwindow->restart_brender(); mwindow->gui->update(1, NORMAL_DRAW, 1, 1, 0, 1, 0); @@ -758,8 +701,7 @@ int CWindowGUI::drag_stop() } } - if(mwindow->session->current_operation == DRAG_VEFFECT) - { + if( mwindow->session->current_operation == DRAG_VEFFECT ) { //printf("CWindowGUI::drag_stop 1\n"); Track *affected_track = cwindow->calculate_affected_track(); //printf("CWindowGUI::drag_stop 2\n"); @@ -770,8 +712,7 @@ int CWindowGUI::drag_stop() mwindow->gui->unlock_window(); } - if(mwindow->session->current_operation == DRAG_VTRANSITION) - { + if( mwindow->session->current_operation == DRAG_VTRANSITION ) { Track *affected_track = cwindow->calculate_affected_track(); mwindow->gui->lock_window("CWindowGUI::drag_stop 4"); mwindow->paste_transition_cwindow(affected_track); @@ -784,8 +725,7 @@ int CWindowGUI::drag_stop() void CWindowGUI::update_meters() { - if(mwindow->edl->session->cwindow_meter != meters->visible) - { + if( mwindow->edl->session->cwindow_meter != meters->visible ) { meters->set_meters(meters->meter_count, mwindow->edl->session->cwindow_meter); mwindow->theme->get_cwindow_sizes(this, mwindow->session->cwindow_controls); resize_event(get_w(), get_h()); @@ -882,6 +822,7 @@ void panel_btn(fit_selection,(), fit_selection()) void panel_btn(fit_autos,(int all), fit_autos(all)) void panel_btn(set_editing_mode,(int mode), set_editing_mode(mode)) void panel_btn(set_auto_keyframes,(int v), set_auto_keyframes(v)) +void panel_btn(set_span_keyframes,(int v), set_span_keyframes(v)) void panel_btn(set_labels_follow_edits,(int v), set_labels_follow_edits(v)) @@ -941,7 +882,8 @@ void CWindowZoom::update(double value) int CWindowZoom::handle_event() { double value = !strcasecmp(gui->auto_zoom, get_text()) ? 0 : get_value(); - gui->zoom_canvas(value, 0); + gui->canvas->set_zoom(mwindow->edl, value); + gui->update_canvas(); return 1; } @@ -949,14 +891,7 @@ int CWindowZoom::handle_event() #ifdef USE_SLIDER CWindowSlider::CWindowSlider(MWindow *mwindow, CWindow *cwindow, int x, int y, int pixels) - : BC_PercentageSlider(x, - y, - 0, - pixels, - pixels, - 0, - 1, - 0) + : BC_PercentageSlider(x, y, 0, pixels, pixels, 0, 1, 0) { this->mwindow = mwindow; this->cwindow = cwindow; @@ -997,44 +932,12 @@ int CWindowSlider::decrease_value() lock_window("CWindowSlider::decrease_value"); return 1; } - - -// CWindowDestination::CWindowDestination(MWindow *mwindow, CWindowGUI *cwindow, int x, int y) -// : BC_PopupTextBox(cwindow, -// &cwindow->destinations, -// cwindow->destinations.values[cwindow->cwindow->destination]->get_text(), -// x, -// y, -// 70, -// 200) -// { -// this->mwindow = mwindow; -// this->cwindow = cwindow; -// } -// -// CWindowDestination::~CWindowDestination() -// { -// } -// -// int CWindowDestination::handle_event() -// { -// return 1; -// } #endif // USE_SLIDER - - - - CWindowTransport::CWindowTransport(MWindow *mwindow, - CWindowGUI *gui, - int x, - int y) - : PlayTransport(mwindow, - gui, - x, - y) + CWindowGUI *gui, int x, int y) + : PlayTransport(mwindow, gui, x, y) { this->gui = gui; } @@ -1071,18 +974,16 @@ void CWindowTransport::goto_end() CWindowCanvas::CWindowCanvas(MWindow *mwindow, CWindowGUI *gui) - : Canvas(mwindow, - gui, - mwindow->theme->ccanvas_x, - mwindow->theme->ccanvas_y, - mwindow->theme->ccanvas_w, - mwindow->theme->ccanvas_h, - 0, - 0, - mwindow->edl->session->cwindow_scrollbars) + : Canvas(mwindow, gui, + mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y, + mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h, + 0, 0, mwindow->edl->session->cwindow_scrollbars) { this->mwindow = mwindow; this->gui = gui; + last_xscroll = 0; + last_yscroll = 0; + last_zoom = 0; } void CWindowCanvas::status_event() @@ -1090,29 +991,34 @@ void CWindowCanvas::status_event() gui->draw_status(1); } -int CWindowCanvas::get_fullscreen() -{ - return mwindow->session->cwindow_fullscreen; -} - -void CWindowCanvas::set_fullscreen(int value) -{ - mwindow->session->cwindow_fullscreen = value; -} - - void CWindowCanvas::update_zoom(int x, int y, float zoom) { - use_scrollbars = mwindow->edl->session->cwindow_scrollbars; - mwindow->edl->session->cwindow_xscroll = x; mwindow->edl->session->cwindow_yscroll = y; mwindow->edl->session->cwindow_zoom = zoom; + use_scrollbars = !zoom ? 0 : 1; + mwindow->edl->session->cwindow_scrollbars = use_scrollbars; } -void CWindowCanvas::zoom_auto() +int CWindowCanvas::set_fullscreen(int on, int unlock) { - gui->zoom_canvas(0, 1); + int ret = 0; + if( on && !get_fullscreen() ) { + last_xscroll = get_xscroll(); + last_yscroll = get_yscroll(); + last_zoom = get_zoom(); + Canvas::set_fullscreen(1, unlock); + zoom_auto(); + ret = 1; + } + if( !on && get_fullscreen() ) { + Canvas::set_fullscreen(0, unlock); + gui->zoom_panel->update(get_zoom()); + update_zoom(last_xscroll, last_yscroll, last_zoom); + gui->update_canvas(); + ret = 1; + } + return ret; } int CWindowCanvas::get_xscroll() @@ -1131,45 +1037,51 @@ float CWindowCanvas::get_zoom() return mwindow->edl->session->cwindow_zoom; } -void CWindowCanvas::draw_refresh(int flush) +void CWindowCanvas::zoom_auto() { - if(get_canvas() && !get_canvas()->get_video_on()) - { + use_scrollbars = 0; + set_zoom(mwindow->edl, 0); + gui->update_canvas(); +} - if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) - { +int CWindowCanvas::do_scroll(EDL *edl, float cursor_x, float cursor_y) +{ + float zoom = get_zoom(); + float zoom_x, zoom_y, conformed_w, conformed_h; + get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h); + if( !zoom ) { + x = get_x_offset(mwindow->edl, 0, zoom_x, conformed_w, conformed_h); + y = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h); + zoom = get_auto_zoom(mwindow->edl); + } + else { + x = gui->x_origin - cursor_x / zoom_x; + y = gui->y_origin - cursor_y / zoom_y; + } + update_zoom(x, y, zoom); + gui->update_canvas(); + return 1; +} + +void CWindowCanvas::draw_refresh(int flush) +{ + BC_WindowBase *window = get_canvas(); + if( window && !window->get_video_on() ) { + clear(0); + if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) { float in_x1, in_y1, in_x2, in_y2; float out_x1, out_y1, out_x2, out_y2; get_transfers(mwindow->edl, - in_x1, - in_y1, - in_x2, - in_y2, - out_x1, - out_y1, - out_x2, - out_y2); - - if(!EQUIV(out_x1, 0) || - !EQUIV(out_y1, 0) || - !EQUIV(out_x2, get_canvas()->get_w()) || - !EQUIV(out_y2, get_canvas()->get_h())) - { - get_canvas()->clear_box(0, - 0, - get_canvas()->get_w(), - get_canvas()->get_h()); - } + in_x1, in_y1, in_x2, in_y2, + out_x1, out_y1, out_x2, out_y2); + //printf("CWindowCanvas::draw_refresh %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n", //in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2); - if(out_x2 > out_x1 && - out_y2 > out_y1 && - in_x2 > in_x1 && - in_y2 > in_y1) - { + if( out_x2 > out_x1 && out_y2 > out_y1 && + in_x2 > in_x1 && in_y2 > in_y1 ) { // input scaled from session to refresh frame coordinates int ow = get_output_w(mwindow->edl); int oh = get_output_h(mwindow->edl); @@ -1181,37 +1093,25 @@ void CWindowCanvas::draw_refresh(int flush) in_y1 *= ys; in_y2 *= ys; // Can't use OpenGL here because it is called asynchronously of the // playback operation. - get_canvas()->draw_vframe(refresh_frame, - (int)out_x1, - (int)out_y1, + window->draw_vframe(refresh_frame, + (int)out_x1, (int)out_y1, (int)(out_x2 - out_x1), (int)(out_y2 - out_y1), - (int)in_x1, - (int)in_y1, + (int)in_x1, (int)in_y1, (int)(in_x2 - in_x1), (int)(in_y2 - in_y1), 0); } } - else - { - get_canvas()->clear_box(0, - 0, - get_canvas()->get_w(), - get_canvas()->get_h()); - } - +//usleep(10000); draw_overlays(); -// allow last opengl write to complete before redraw -// tried sync_display, glFlush, glxMake*Current(0..) -usleep(20000); - get_canvas()->flash(flush); + window->flash(flush); } //printf("CWindowCanvas::draw_refresh 10\n"); } -#define CROPHANDLE_W 10 -#define CROPHANDLE_H 10 +#define CROPHANDLE_W xS(10) +#define CROPHANDLE_H yS(10) void CWindowCanvas::draw_crophandle(int x, int y) { @@ -1219,32 +1119,25 @@ void CWindowCanvas::draw_crophandle(int x, int y) } - - - - -#define CONTROL_W 10 -#define CONTROL_H 10 -#define FIRST_CONTROL_W 20 -#define FIRST_CONTROL_H 20 +#define CONTROL_W xS(10) +#define CONTROL_H yS(10) +#define FIRST_CONTROL_W xS(20) +#define FIRST_CONTROL_H yS(20) #undef BC_INFINITY #define BC_INFINITY 65536 -#define RULERHANDLE_W 16 -#define RULERHANDLE_H 16 - +#define RULERHANDLE_W xS(16) +#define RULERHANDLE_H yS(16) - -int CWindowCanvas::do_ruler(int draw, - int motion, - int button_press, - int button_release) +int CWindowCanvas::do_ruler(int draw, int motion, + int button_press, int button_release) { int result = 0; - float x1 = mwindow->edl->session->ruler_x1; - float y1 = mwindow->edl->session->ruler_y1; - float x2 = mwindow->edl->session->ruler_x2; - float y2 = mwindow->edl->session->ruler_y2; + EDLSession *session = mwindow->edl->session; + float x1 = session->ruler_x1; + float y1 = session->ruler_y1; + float x2 = session->ruler_x2; + float y2 = session->ruler_y2; float canvas_x1 = x1; float canvas_y1 = y1; float canvas_x2 = x2; @@ -1260,32 +1153,28 @@ int CWindowCanvas::do_ruler(int draw, mwindow->session->cwindow_output_x = roundf(output_x); mwindow->session->cwindow_output_y = roundf(output_y); - if(button_press && get_buttonpress() == 1) - { + if( button_press && get_buttonpress() == 1 ) { gui->ruler_handle = -1; gui->ruler_translate = 0; - if(gui->alt_down()) - { + if( gui->alt_down() ) { gui->ruler_translate = 1; gui->ruler_origin_x = x1; gui->ruler_origin_y = y1; } else - if(canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 && + if( canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 && canvas_cursor_x < canvas_x1 + RULERHANDLE_W / 2 && canvas_cursor_y >= canvas_y1 - RULERHANDLE_W && - canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2) - { + canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2 ) { gui->ruler_handle = 0; gui->ruler_origin_x = x1; gui->ruler_origin_y = y1; } else - if(canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 && + if( canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 && canvas_cursor_x < canvas_x2 + RULERHANDLE_W / 2 && canvas_cursor_y >= canvas_y2 - RULERHANDLE_W && - canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2) - { + canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2 ) { gui->ruler_handle = 1; gui->ruler_origin_x = x2; gui->ruler_origin_y = y2; @@ -1293,21 +1182,20 @@ int CWindowCanvas::do_ruler(int draw, // Start new selection - if(!gui->ruler_translate && + if( !gui->ruler_translate && (gui->ruler_handle < 0 || (EQUIV(x2, x1) && - EQUIV(y2, y1)))) - { + EQUIV(y2, y1))) ) { // Hide previous do_ruler(1, 0, 0, 0); get_canvas()->flash(); gui->ruler_handle = 1; - mwindow->edl->session->ruler_x1 = output_x; - mwindow->edl->session->ruler_y1 = output_y; - mwindow->edl->session->ruler_x2 = output_x; - mwindow->edl->session->ruler_y2 = output_y; - gui->ruler_origin_x = mwindow->edl->session->ruler_x2; - gui->ruler_origin_y = mwindow->edl->session->ruler_y2; + session->ruler_x1 = output_x; + session->ruler_y1 = output_y; + session->ruler_x2 = output_x; + session->ruler_y2 = output_y; + gui->ruler_origin_x = session->ruler_x2; + gui->ruler_origin_y = session->ruler_y2; } gui->x_origin = output_x; @@ -1317,73 +1205,62 @@ int CWindowCanvas::do_ruler(int draw, result = 1; } - if(motion) - { - if(gui->current_operation == CWINDOW_RULER) - { - if(gui->ruler_translate) - { + if( motion ) { + if( gui->current_operation == CWINDOW_RULER ) { + if( gui->ruler_translate ) { // Hide ruler do_ruler(1, 0, 0, 0); - float x_difference = mwindow->edl->session->ruler_x1; - float y_difference = mwindow->edl->session->ruler_y1; - mwindow->edl->session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x; - mwindow->edl->session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y; - x_difference -= mwindow->edl->session->ruler_x1; - y_difference -= mwindow->edl->session->ruler_y1; - mwindow->edl->session->ruler_x2 -= x_difference; - mwindow->edl->session->ruler_y2 -= y_difference; + float x_difference = session->ruler_x1; + float y_difference = session->ruler_y1; + session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x; + session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y; + x_difference -= session->ruler_x1; + y_difference -= session->ruler_y1; + session->ruler_x2 -= x_difference; + session->ruler_y2 -= y_difference; // Show ruler do_ruler(1, 0, 0, 0); get_canvas()->flash(); gui->update_tool(); } - else - switch(gui->ruler_handle) - { + else { + switch( gui->ruler_handle ) { case 0: do_ruler(1, 0, 0, 0); - mwindow->edl->session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x; - mwindow->edl->session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y; - if(gui->alt_down() || gui->ctrl_down()) - { - double angle_value = fabs(atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) / - (mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) * - 360 / - 2 / - M_PI); + session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x; + session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y; + if( gui->alt_down() || gui->ctrl_down() ) { + double angle_value = fabs(atan((session->ruler_y2 - session->ruler_y1) / + (session->ruler_x2 - session->ruler_x1)) * + 360 / 2 / M_PI); double distance_value = - sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) + - SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1)); - if(angle_value < 22) - mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2; + sqrt(SQR(session->ruler_x2 - session->ruler_x1) + + SQR(session->ruler_y2 - session->ruler_y1)); + if( angle_value < 22 ) + session->ruler_y1 = session->ruler_y2; else - if(angle_value > 67) - mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2; + if( angle_value > 67 ) + session->ruler_x1 = session->ruler_x2; else - if(mwindow->edl->session->ruler_x1 < mwindow->edl->session->ruler_x2 && - mwindow->edl->session->ruler_y1 < mwindow->edl->session->ruler_y2) - { - mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 - distance_value / 1.414214; - mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 - distance_value / 1.414214; + if( session->ruler_x1 < session->ruler_x2 && + session->ruler_y1 < session->ruler_y2 ) { + session->ruler_x1 = session->ruler_x2 - distance_value / 1.414214; + session->ruler_y1 = session->ruler_y2 - distance_value / 1.414214; } else - if(mwindow->edl->session->ruler_x1 < mwindow->edl->session->ruler_x2 && mwindow->edl->session->ruler_y1 > mwindow->edl->session->ruler_y2) - { - mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 - distance_value / 1.414214; - mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 + distance_value / 1.414214; + if( session->ruler_x1 < session->ruler_x2 && session->ruler_y1 > session->ruler_y2 ) { + session->ruler_x1 = session->ruler_x2 - distance_value / 1.414214; + session->ruler_y1 = session->ruler_y2 + distance_value / 1.414214; } else - if(mwindow->edl->session->ruler_x1 > mwindow->edl->session->ruler_x2 && - mwindow->edl->session->ruler_y1 < mwindow->edl->session->ruler_y2) - { - mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 + distance_value / 1.414214; - mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 - distance_value / 1.414214; + if( session->ruler_x1 > session->ruler_x2 && + session->ruler_y1 < session->ruler_y2 ) { + session->ruler_x1 = session->ruler_x2 + distance_value / 1.414214; + session->ruler_y1 = session->ruler_y2 - distance_value / 1.414214; } - else - { - mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 + distance_value / 1.414214; - mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 + distance_value / 1.414214; + else { + session->ruler_x1 = session->ruler_x2 + distance_value / 1.414214; + session->ruler_y1 = session->ruler_y2 + distance_value / 1.414214; } } do_ruler(1, 0, 0, 0); @@ -1393,76 +1270,67 @@ int CWindowCanvas::do_ruler(int draw, case 1: do_ruler(1, 0, 0, 0); - mwindow->edl->session->ruler_x2 = output_x - gui->x_origin + gui->ruler_origin_x; - mwindow->edl->session->ruler_y2 = output_y - gui->y_origin + gui->ruler_origin_y; - if(gui->alt_down() || gui->ctrl_down()) - { - double angle_value = fabs(atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) / - (mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) * - 360 / - 2 / - M_PI); + session->ruler_x2 = output_x - gui->x_origin + gui->ruler_origin_x; + session->ruler_y2 = output_y - gui->y_origin + gui->ruler_origin_y; + if( gui->alt_down() || gui->ctrl_down() ) { + double angle_value = fabs(atan((session->ruler_y2 - session->ruler_y1) / + (session->ruler_x2 - session->ruler_x1)) * + 360 / 2 / M_PI); double distance_value = - sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) + - SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1)); - if(angle_value < 22) - mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1; + sqrt(SQR(session->ruler_x2 - session->ruler_x1) + + SQR(session->ruler_y2 - session->ruler_y1)); + if( angle_value < 22 ) + session->ruler_y2 = session->ruler_y1; else - if(angle_value > 67) - mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1; + if( angle_value > 67 ) + session->ruler_x2 = session->ruler_x1; else - if(mwindow->edl->session->ruler_x2 < mwindow->edl->session->ruler_x1 && - mwindow->edl->session->ruler_y2 < mwindow->edl->session->ruler_y1) - { - mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 - distance_value / 1.414214; - mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 - distance_value / 1.414214; + if( session->ruler_x2 < session->ruler_x1 && + session->ruler_y2 < session->ruler_y1 ) { + session->ruler_x2 = session->ruler_x1 - distance_value / 1.414214; + session->ruler_y2 = session->ruler_y1 - distance_value / 1.414214; } else - if(mwindow->edl->session->ruler_x2 < mwindow->edl->session->ruler_x1 && - mwindow->edl->session->ruler_y2 > mwindow->edl->session->ruler_y1) - { - mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 - distance_value / 1.414214; - mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 + distance_value / 1.414214; + if( session->ruler_x2 < session->ruler_x1 && + session->ruler_y2 > session->ruler_y1 ) { + session->ruler_x2 = session->ruler_x1 - distance_value / 1.414214; + session->ruler_y2 = session->ruler_y1 + distance_value / 1.414214; } else - if(mwindow->edl->session->ruler_x2 > mwindow->edl->session->ruler_x1 && mwindow->edl->session->ruler_y2 < mwindow->edl->session->ruler_y1) - { - mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 + distance_value / 1.414214; - mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 - distance_value / 1.414214; + if( session->ruler_x2 > session->ruler_x1 && session->ruler_y2 < session->ruler_y1 ) { + session->ruler_x2 = session->ruler_x1 + distance_value / 1.414214; + session->ruler_y2 = session->ruler_y1 - distance_value / 1.414214; } - else - { - mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 + distance_value / 1.414214; - mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 + distance_value / 1.414214; + else { + session->ruler_x2 = session->ruler_x1 + distance_value / 1.414214; + session->ruler_y2 = session->ruler_y1 + distance_value / 1.414214; } } do_ruler(1, 0, 0, 0); get_canvas()->flash(); gui->update_tool(); break; + } } //printf("CWindowCanvas::do_ruler 2 %f %f %f %f\n", gui->ruler_x1, gui->ruler_y1, gui->ruler_x2, gui->ruler_y2); } - else - { + else { // printf("CWindowCanvas::do_ruler 2 %f %f %f %f\n", // canvas_cursor_x, // canvas_cursor_y, // canvas_x1, // canvas_y1); - if(canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 && + if( canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 && canvas_cursor_x < canvas_x1 + RULERHANDLE_W / 2 && canvas_cursor_y >= canvas_y1 - RULERHANDLE_W && - canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2) - { + canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2 ) { set_cursor(UPRIGHT_ARROW_CURSOR); } else - if(canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 && + if( canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 && canvas_cursor_x < canvas_x2 + RULERHANDLE_W / 2 && canvas_cursor_y >= canvas_y2 - RULERHANDLE_W && - canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2) - { + canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2 ) { set_cursor(UPRIGHT_ARROW_CURSOR); } else @@ -1474,8 +1342,7 @@ int CWindowCanvas::do_ruler(int draw, } // Assume no ruler measurement if 0 length - if(draw && (!EQUIV(x2, x1) || !EQUIV(y2, y1))) - { + if( draw && (!EQUIV(x2, x1) || !EQUIV(y2, y1)) ) { get_canvas()->set_inverse(); get_canvas()->set_color(WHITE); get_canvas()->draw_line((int)canvas_x1, @@ -1523,36 +1390,39 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, { // Retrieve points from top recordable track //printf("CWindowCanvas::do_mask 1\n"); - Track *track = gui->cwindow->calculate_affected_track(); + Track *track = gui->cwindow->calculate_mask_track(); //printf("CWindowCanvas::do_mask 2\n"); - if(!track) return 0; + if( !track ) return 0; //printf("CWindowCanvas::do_mask 3\n"); - + CWindowMaskGUI *mask_gui = (CWindowMaskGUI *) + (gui->tool_panel ? gui->tool_panel->tool_gui : 0); + int draw_markers = mask_gui ? mask_gui->markers : 0; + int draw_boundary = mask_gui ? mask_gui->boundary : 0; MaskAutos *mask_autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK]; int64_t position = track->to_units( mwindow->edl->local_session->get_selectionstart(1), 0); - ArrayList points; - + Auto *prev_auto = 0; + mask_autos->get_prev_auto(position, PLAY_FORWARD, (Auto *&)prev_auto, 1); + MaskAuto *prev_mask = (MaskAuto *)prev_auto; + MaskPoints points; + int update_points = 1; // Determine the points based on whether // new keyframes will be generated or drawing is performed. // If keyframe generation occurs, use the interpolated mask. // If no keyframe generation occurs, use the previous mask. int use_interpolated = 0; - if(button_press || cursor_motion) { + if( button_press || cursor_motion ) { #ifdef USE_KEYFRAME_SPANNING double selection_start = mwindow->edl->local_session->get_selectionstart(0); double selection_end = mwindow->edl->local_session->get_selectionend(0); - - Auto *first = 0; - mask_autos->get_prev_auto(track->to_units(selection_start, 0), - PLAY_FORWARD, first, 1); - Auto *last = 0; - mask_autos->get_prev_auto(track->to_units(selection_end, 0), - PLAY_FORWARD, last, 1); - - if(last == first && (!mwindow->edl->session->auto_keyframes)) + int64_t start_pos = track->to_units(selection_start, 0); + int64_t end_pos = track->to_units(selection_end, 0); + Auto *first = 0, *last = 0; + mask_autos->get_prev_auto(start_pos, PLAY_FORWARD, first, 1); + mask_autos->get_prev_auto(end_pos, PLAY_FORWARD, last, 1); + if( last == first && (!mwindow->edl->session->auto_keyframes) ) use_interpolated = 0; else // If keyframe spanning occurs, use the interpolated points. @@ -1560,28 +1430,22 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, use_interpolated = 1; #else - if(mwindow->edl->session->auto_keyframes) + if( mwindow->edl->session->auto_keyframes ) use_interpolated = 1; #endif } else use_interpolated = 1; - if(use_interpolated) { + if( use_interpolated ) { // Interpolate the points to get exactly what is being rendered at this position. mask_autos->get_points(&points, mwindow->edl->session->cwindow_mask, - position, - PLAY_FORWARD); + position, PLAY_FORWARD); } else { // Use the prev mask - Auto *prev = 0; - mask_autos->get_prev_auto(position, - PLAY_FORWARD, - prev, - 1); - ((MaskAuto*)prev)->get_points(&points, + prev_mask->get_points(&points, mwindow->edl->session->cwindow_mask); } @@ -1606,7 +1470,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, mask_cursor_y = (mask_cursor_y - projector_y) / projector_z + half_track_h; // Fix cursor origin - if(button_press) { + if( button_press ) { gui->x_origin = mask_cursor_x; gui->y_origin = mask_cursor_y; } @@ -1627,8 +1491,8 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, ArrayList x_points; ArrayList y_points; - if(!cursor_motion) { - if(draw) { + if( !cursor_motion ) { + if( draw ) { get_canvas()->set_color(WHITE); get_canvas()->set_inverse(); } @@ -1636,19 +1500,19 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, // Never draw closed polygon and a closed // polygon is harder to add points to. - for(int i = 0; i < points.size() && !result; i++) { + for( int i = 0; i < points.size() && !result; i++ ) { MaskPoint *point1 = points.get(i); MaskPoint *point2 = (i >= points.size() - 1) ? points.get(0) : points.get(i + 1); - if(button_press) { + if( button_press ) { float point_distance1 = line_dist(point1->x,point1->y, mask_cursor_x,mask_cursor_y); - if(point_distance1 < shortest_point_distance || shortest_point < 0) { + if( point_distance1 < shortest_point_distance || shortest_point < 0 ) { shortest_point_distance = point_distance1; shortest_point = i; } float point_distance2 = line_dist(point2->x,point2->y, mask_cursor_x,mask_cursor_y); - if(point_distance2 < shortest_point_distance || shortest_point < 0) { + if( point_distance2 < shortest_point_distance || shortest_point < 0 ) { shortest_point_distance = point_distance2; shortest_point = (i >= points.size() - 1) ? 0 : (i + 1); } @@ -1658,7 +1522,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, //printf("CWindowCanvas::do_mask 1 %f, %f -> %f, %f projectorz=%f\n", //point1->x, point1->y, point2->x, point2->y, projector_z); - for(int j = 0; j <= segments && !result; j++) { + for( int j = 0; j <= segments && !result; j++ ) { //printf("CWindowCanvas::do_mask 1 %f, %f -> %f, %f\n", x0, y0, x3, y3); float x0 = point1->x, y0 = point1->y; float x1 = point1->x + point1->control_x2; @@ -1693,13 +1557,13 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, float canvas_x = (x - half_track_w) * projector_z + projector_x; float canvas_y = (y - half_track_h) * projector_z + projector_y; // Test new point addition - if(button_press) { + if( button_press ) { float line_distance = line_dist(x,y, mask_cursor_x,mask_cursor_y); //printf("CWindowCanvas::do_mask 1 x=%f cursor_x=%f y=%f cursor_y=%f %f %f %d, %d\n", // x, cursor_x, y, cursor_y, line_distance, shortest_line_distance, shortest_point1, shortest_point2); - if(line_distance < shortest_line_distance || - shortest_point1 < 0) { + if( line_distance < shortest_line_distance || + shortest_point1 < 0 ) { shortest_line_distance = line_distance; shortest_point1 = i; shortest_point2 = (i >= points.size() - 1) ? 0 : (i + 1); @@ -1709,19 +1573,19 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, // Test existing point selection // Test first point - if(gui->ctrl_down()) { + if( gui->ctrl_down() ) { float distance = line_dist(x1,y1, mask_cursor_x,mask_cursor_y); - if(distance < selected_control_point_distance) { + if( distance < selected_control_point_distance ) { selected_point = i; selected_control_point = 1; selected_control_point_distance = distance; } } else { - if(!gui->shift_down()) { + if( !gui->shift_down() ) { output_to_canvas(mwindow->edl, 0, canvas_x0, canvas_y0); - if(test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0)) { + if( test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0) ) { selected_point = i; } } @@ -1730,20 +1594,20 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, } } // Test second point - if(gui->ctrl_down()) { + if( gui->ctrl_down() ) { float distance = line_dist(x2,y2, mask_cursor_x,mask_cursor_y); //printf("CWindowCanvas::do_mask %d %f %f\n", i, distance, selected_control_point_distance); - if(distance < selected_control_point_distance) { + if( distance < selected_control_point_distance ) { selected_point = (i < points.size() - 1 ? i + 1 : 0); selected_control_point = 0; selected_control_point_distance = distance; } } - else if(i < points.size() - 1) { - if(!gui->shift_down()) { + else if( i < points.size() - 1 ) { + if( !gui->shift_down() ) { output_to_canvas(mwindow->edl, 0, canvas_x3, canvas_y3); - if(test_bbox(cursor_x, cursor_y, canvas_x3, canvas_y3)) { + if( test_bbox(cursor_x, cursor_y, canvas_x3, canvas_y3) ) { selected_point = (i < points.size() - 1 ? i + 1 : 0); } } @@ -1755,17 +1619,17 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y); - if(j > 0) { + if( j > 0 ) { - if(draw) { // Draw joining line + if( draw ) { // Draw joining line x_points.append((int)canvas_x); y_points.append((int)canvas_y); } - if(j == segments) { - if(draw) { // Draw second anchor - if(i < points.size() - 1) { - if(i == gui->affected_point - 1) + if( j == segments ) { + if( draw && draw_markers ) { // Draw second anchor + if( i < points.size() - 1 ) { + if( i == gui->affected_point - 1 ) get_canvas()->draw_disc( (int)canvas_x - CONTROL_W / 2, (int)canvas_y - CONTROL_W / 2, @@ -1793,23 +1657,29 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, } else { // Draw first anchor - if(i == 0 && draw) { - char mask_label[BCSTRLEN]; - sprintf(mask_label, "%d", - mwindow->edl->session->cwindow_mask); - get_canvas()->draw_text( - (int)canvas_x - FIRST_CONTROL_W, - (int)canvas_y - FIRST_CONTROL_H, - mask_label); - - get_canvas()->draw_disc( - (int)canvas_x - FIRST_CONTROL_W / 2, - (int)canvas_y - FIRST_CONTROL_H / 2, - FIRST_CONTROL_W, FIRST_CONTROL_H); + if( i == 0 && draw ) { + if( draw_boundary ) { + char mask_label[BCSTRLEN]; + int k = mwindow->edl->session->cwindow_mask; + if( !prev_mask || k < 0 || k >= prev_mask->masks.size() ) + sprintf(mask_label, "%d", k); + else + sprintf(mask_label, "%s", prev_mask->masks[k]->name); + get_canvas()->draw_text( + (int)canvas_x - FIRST_CONTROL_W, + (int)canvas_y - FIRST_CONTROL_H, + mask_label); + } + if( draw_markers ) { + get_canvas()->draw_disc( + (int)canvas_x - FIRST_CONTROL_W / 2, + (int)canvas_y - FIRST_CONTROL_H / 2, + FIRST_CONTROL_W, FIRST_CONTROL_H); + } } // Draw first control point. - if(draw) { + if( draw && draw_markers ) { output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1); get_canvas()->draw_line( (int)canvas_x, (int)canvas_y, @@ -1829,60 +1699,116 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, } //printf("CWindowCanvas::do_mask 1\n"); - if(draw) { - get_canvas()->draw_polygon(&x_points, &y_points); - get_canvas()->set_opaque(); + BC_WindowBase *cvs_win = get_canvas(); + if( draw && draw_boundary ) { + cvs_win->draw_polygon(&x_points, &y_points); + cvs_win->set_opaque(); + } + if( draw && mask_gui && mask_gui->focused ) { + float fx = atof(mask_gui->focus_x->get_text()); + float fy = atof(mask_gui->focus_y->get_text()); + fx = (fx - half_track_w) * projector_z + projector_x; + fy = (fy - half_track_h) * projector_z + projector_y; + output_to_canvas(mwindow->edl, 0, fx, fy); + float r = bmax(cvs_win->get_w(), cvs_win->get_h()); + float d = 0.005*r; +#if 1 + int fw = 2*d+3, fh = fw; + VFrame focus(fw,fh, BC_RGBA8888); + focus.transfer_from(gui->focus_frame); + fx -= fw/2.f; fy -= fh/2.f; + BC_Pixmap focus_pixmap(cvs_win, &focus, PIXMAP_ALPHA); + cvs_win->draw_pixmap(&focus_pixmap,fx,fy); +#else + cvs_win->set_line_width((int)(0.0025*r) + 1); + cvs_win->set_color(BLUE); + cvs_win->draw_line(fx-d,fy-d, fx+d, fy+d); + cvs_win->draw_line(fx-d,fy+d, fx+d, fy-d); + cvs_win->set_line_width(0); + cvs_win->set_color(WHITE); +#endif + } + if( draw && mask_gui && draw_markers && points.size() ) { + float cx = 0, cy = 0; + int n = points.size(); + for( int i=0; ix; cy += point->y; + } + cx /= n; cy /= n; + if( !mask_gui->focused ) + mask_gui->set_focused(0, cx, cy); + cx = (cx - half_track_w) * projector_z + projector_x; + cy = (cy - half_track_h) * projector_z + projector_y; + output_to_canvas(mwindow->edl, 0, cx, cy); + float r = bmax(cvs_win->get_w(), cvs_win->get_h()); + float d = 0.007*r; + cvs_win->set_line_width((int)(0.002*r) + 1); + cvs_win->set_color(ORANGE); + cvs_win->draw_line(cx-d,cy, cx+d, cy); + cvs_win->draw_line(cx,cy-d, cx, cy+d); + cvs_win->set_line_width(0); + cvs_win->set_color(WHITE); } //printf("CWindowCanvas::do_mask 1\n"); } - if(button_press && !result) { - gui->affected_track = gui->cwindow->calculate_affected_track(); + if( button_press && !result ) { + gui->affected_track = gui->cwindow->calculate_mask_track(); // Get keyframe outside the EDL to edit. This must be rendered // instead of the EDL keyframes when it exists. Then it must be // applied to the EDL keyframes on buttonrelease. - if(gui->affected_track) { + if( gui->affected_track ) { #ifdef USE_KEYFRAME_SPANNING // Make copy of current parameters in local keyframe gui->mask_keyframe = (MaskAuto*)gui->cwindow->calculate_affected_auto( - mask_autos, - 0); + mask_autos, 0); gui->orig_mask_keyframe->copy_data(gui->mask_keyframe); #else gui->mask_keyframe = (MaskAuto*)gui->cwindow->calculate_affected_auto( - mask_autos, - 1); + mask_autos, 1); #endif } SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask); - + if( get_buttonpress() == WHEEL_UP || get_buttonpress() == WHEEL_DOWN ) { + if( !gui->shift_down() ) { + mwindow->undo->update_undo_before(_("mask rotate"), this); + gui->current_operation = CWINDOW_MASK_ROTATE; + } + else { + mwindow->undo->update_undo_before(_("mask scale"), this); + gui->current_operation = CWINDOW_MASK_SCALE; + } + gui->affected_point = 0; + } + else // Translate entire keyframe - if(gui->alt_down() && mask->points.size()) { + if( gui->alt_down() && mask->points.size() ) { mwindow->undo->update_undo_before(_("mask translate"), 0); gui->current_operation = CWINDOW_MASK_TRANSLATE; gui->affected_point = 0; } else // Existing point or control point was selected - if(selected_point >= 0) { + if( selected_point >= 0 ) { mwindow->undo->update_undo_before(_("mask adjust"), 0); gui->affected_point = selected_point; - if(selected_control_point == 0) + if( selected_control_point == 0 ) gui->current_operation = CWINDOW_MASK_CONTROL_IN; else - if(selected_control_point == 1) + if( selected_control_point == 1 ) gui->current_operation = CWINDOW_MASK_CONTROL_OUT; else gui->current_operation = mwindow->edl->session->cwindow_operation; } else // No existing point or control point was selected so create a new one - if(!gui->ctrl_down() && !gui->alt_down()) { + if( !gui->ctrl_down() && !gui->alt_down() ) { mwindow->undo->update_undo_before(_("mask point"), 0); // Create the template MaskPoint *point = new MaskPoint; @@ -1894,7 +1820,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, point->control_y2 = 0; - if(shortest_point2 < shortest_point1) { + if( shortest_point2 < shortest_point1 ) { shortest_point2 ^= shortest_point1; shortest_point1 ^= shortest_point2; shortest_point2 ^= shortest_point1; @@ -1925,12 +1851,12 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, #else // Need to apply the new point to every keyframe - for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) { + for( MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) { SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask); MaskPoint *new_point = new MaskPoint; submask->points.append(new_point); *new_point = *point; - if(current == (MaskAuto*)mask_autos->default_auto) + if( current == (MaskAuto*)mask_autos->default_auto ) current = (MaskAuto*)mask_autos->first; else current = (MaskAuto*)NEXT; @@ -1942,17 +1868,17 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, } else // Insert between 2 points, shifting back point 2 - if(shortest_point1 >= 0 && shortest_point2 >= 0) { + if( shortest_point1 >= 0 && shortest_point2 >= 0 ) { #ifdef USE_KEYFRAME_SPANNING // In case the keyframe point count isn't synchronized with the rest of the keyframes, // avoid a crash. - if(points.size() >= shortest_point2) { + if( points.size() >= shortest_point2 ) { MaskPoint *new_point = new MaskPoint; points.append(0); - for(int i = points.size() - 1; + for( int i = points.size() - 1; i > shortest_point2; - i--) + i-- ) points.values[i] = points.values[i - 1]; points.values[shortest_point2] = new_point; @@ -1961,23 +1887,23 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, #else - for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) { + for( MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) { SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask); // In case the keyframe point count isn't synchronized with the rest of the keyframes, // avoid a crash. - if(submask->points.size() >= shortest_point2) { + if( submask->points.size() >= shortest_point2 ) { MaskPoint *new_point = new MaskPoint; submask->points.append(0); - for(int i = submask->points.size() - 1; + for( int i = submask->points.size() - 1; i > shortest_point2; - i--) + i-- ) submask->points.values[i] = submask->points.values[i - 1]; submask->points.values[shortest_point2] = new_point; *new_point = *point; } - if(current == (MaskAuto*)mask_autos->default_auto) + if( current == (MaskAuto*)mask_autos->default_auto ) current = (MaskAuto*)mask_autos->first; else current = (MaskAuto*)NEXT; @@ -1993,7 +1919,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, // mwindow->edl->dump(); // printf("CWindowGUI::do_mask 30\n"); - if(!result) { + if( !result ) { //printf("CWindowCanvas::do_mask 1\n"); // Create the first point. #ifdef USE_KEYFRAME_SPANNING @@ -2002,12 +1928,12 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, *new_point = *point; gui->affected_point = points.size() - 1; #else - for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) { + for( MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) { SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask); MaskPoint *new_point = new MaskPoint; submask->points.append(new_point); *new_point = *point; - if(current == (MaskAuto*)mask_autos->default_auto) + if( current == (MaskAuto*)mask_autos->default_auto ) current = (MaskAuto*)mask_autos->first; else current = (MaskAuto*)NEXT; @@ -2028,54 +1954,56 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, redraw = 1; } - if(button_press && result) { + if( button_press && result ) { #ifdef USE_KEYFRAME_SPANNING - MaskPoint *point = points.values[gui->affected_point]; - gui->center_x = point->x; - gui->center_y = point->y; - gui->control_in_x = point->control_x1; - gui->control_in_y = point->control_y1; - gui->control_out_x = point->control_x2; - gui->control_out_y = point->control_y2; - gui->tool_panel->raise_window(); + MaskPoints &mask_points = points; #else SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask); - MaskPoint *point = mask->points.values[gui->affected_point]; - gui->center_x = point->x; - gui->center_y = point->y; - gui->control_in_x = point->control_x1; - gui->control_in_y = point->control_y1; - gui->control_out_x = point->control_x2; - gui->control_out_y = point->control_y2; - gui->tool_panel->raise_window(); + MaskPoints &mask_points = mask->points; #endif + int k = gui->affected_point; + if( k >= 0 && k < mask_points.size() ) { + MaskPoint *point = mask_points.values[k]; + gui->center_x = point->x; + gui->center_y = point->y; + gui->control_in_x = point->control_x1; + gui->control_in_y = point->control_y1; + gui->control_out_x = point->control_x2; + gui->control_out_y = point->control_y2; + } + else { + gui->center_x = gui->center_y = 0; + gui->control_in_x = gui->control_in_y = 0; + gui->control_out_x = gui->control_out_y = 0; + } + gui->tool_panel->raise_window(); } //printf("CWindowCanvas::do_mask 8\n"); - if(cursor_motion) { + if( cursor_motion ) { #ifdef USE_KEYFRAME_SPANNING // Must update the reference keyframes for every cursor motion - gui->mask_keyframe = - (MaskAuto*)gui->cwindow->calculate_affected_auto( - mask_autos, - 0); + gui->mask_keyframe = (MaskAuto*)gui->cwindow-> + calculate_affected_auto(mask_autos, 0); gui->orig_mask_keyframe->copy_data(gui->mask_keyframe); #endif //printf("CWindowCanvas::do_mask %d %d\n", __LINE__, gui->affected_point); SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask); - if( gui->affected_point >= 0 && gui->affected_point < mask->points.size() && - gui->current_operation != CWINDOW_NONE) { + if( mask && gui->affected_point >= 0 && + gui->affected_point < mask->points.size() && + gui->current_operation != CWINDOW_NONE ) { // mwindow->undo->update_undo_before(_("mask point"), this); #ifdef USE_KEYFRAME_SPANNING - MaskPoint *point = points.get(gui->affected_point); + MaskPoints &mask_points = points; #else - MaskPoint *point = mask->points.get(gui->affected_point); + MaskPoints &mask_points = mask->points; #endif + MaskPoint *point = mask_points.get(gui->affected_point); // canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y); -//printf("CWindowCanvas::do_mask 9 %d %d\n", mask->points.size(), gui->affected_point); +//printf("CWindowCanvas::do_mask 9 %d %d\n", mask_points.size(), gui->affected_point); float last_x = point->x; float last_y = point->y; @@ -2083,56 +2011,134 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, float last_control_y1 = point->control_y1; float last_control_x2 = point->control_x2; float last_control_y2 = point->control_y2; + int rotate = 0; - switch(gui->current_operation) { - case CWINDOW_MASK: + switch( gui->current_operation ) { + case CWINDOW_MASK: //printf("CWindowCanvas::do_mask %d %d\n", __LINE__, gui->affected_point); - point->x = mask_cursor_x - gui->x_origin + gui->center_x; - point->y = mask_cursor_y - gui->y_origin + gui->center_y; - break; + point->x = mask_cursor_x - gui->x_origin + gui->center_x; + point->y = mask_cursor_y - gui->y_origin + gui->center_y; + break; - case CWINDOW_MASK_CONTROL_IN: - point->control_x1 = mask_cursor_x - gui->x_origin + gui->control_in_x; - point->control_y1 = mask_cursor_y - gui->y_origin + gui->control_in_y; - break; + case CWINDOW_MASK_CONTROL_IN: + point->control_x1 = mask_cursor_x - gui->x_origin + gui->control_in_x; + point->control_y1 = mask_cursor_y - gui->y_origin + gui->control_in_y; + break; - case CWINDOW_MASK_CONTROL_OUT: - point->control_x2 = mask_cursor_x - gui->x_origin + gui->control_out_x; - point->control_y2 = mask_cursor_y - gui->y_origin + gui->control_out_y; - break; + case CWINDOW_MASK_CONTROL_OUT: + point->control_x2 = mask_cursor_x - gui->x_origin + gui->control_out_x; + point->control_y2 = mask_cursor_y - gui->y_origin + gui->control_out_y; + break; - case CWINDOW_MASK_TRANSLATE: -#ifdef USE_KEYFRAME_SPANNING - for(int i = 0; i < points.size(); i++) { - points.values[i]->x += mask_cursor_x - gui->x_origin; - points.values[i]->y += mask_cursor_y - gui->y_origin; + case CWINDOW_MASK_TRANSLATE: { + if( !mask_gui ) break; + int mode = mask_gui->scale_mode; + MaskAuto *keyframe = gui->mask_keyframe; + int gang = mask_gui->gang_focus->get_value(); + float dx = mask_cursor_x - gui->x_origin; + float dy = mask_cursor_y - gui->y_origin; + if( !dx && !dy ) break; + int k = mwindow->edl->session->cwindow_mask; + int n = gang ? keyframe->masks.size() : k+1; + for( int j=gang? 0 : k; jmask_enables[j]->get_value() ) continue; + SubMask *sub_mask = keyframe->get_submask(j); + if( !sub_mask ) continue; + MaskPoints &points = sub_mask->points; + for( int i=0; ix += dx; + if( mode == MASK_SCALE_Y || mode == MASK_SCALE_XY ) point->y += dy; } -#else - for(int i = 0; i < mask->points.size(); i++) { - mask->points.values[i]->x += mask_cursor_x - gui->x_origin; - mask->points.values[i]->y += mask_cursor_y - gui->y_origin; + } + gui->x_origin = mask_cursor_x; + gui->y_origin = mask_cursor_y; + rerender = 1; + redraw = 1; + update_points = 0; + break; } + case CWINDOW_MASK_ROTATE: + rotate = 1; + case CWINDOW_MASK_SCALE: { + if( !mask_gui || !mask_points.size() ) break; + float cx = gui->x_origin, cy = gui->y_origin; + if( mask_gui->focused ) { + cx = atof(mask_gui->focus_x->get_text()); + cy = atof(mask_gui->focus_y->get_text()); + } + else if( !gui->ctrl_down() ) { + cx = cy = 0; + int n = mask_points.size(); + for( int i=0; ix; cy += point->y; } -#endif - gui->x_origin = mask_cursor_x; - gui->y_origin = mask_cursor_y; - break; + cx /= n; cy /= n; + mask_gui->set_focused(0, cx, cy); + } + gui->x_origin = cx; + gui->y_origin = cy; + double accel = + gui->get_triple_click() ? 8. : + gui->get_double_click() ? 4. : + 1.; + int button_no = get_buttonpress(); + double ds = accel/64., dt = accel*M_PI/360.; + double scale = button_no == WHEEL_UP ? 1.+ds : 1.-ds; + int mode = mask_gui->scale_mode; + double xscale = !rotate && (mode == MASK_SCALE_X || + mode == MASK_SCALE_XY ) ? scale : 1.; + double yscale = !rotate && (mode == MASK_SCALE_Y || + mode == MASK_SCALE_XY ) ? scale : 1.; + double theta = button_no == WHEEL_UP ? dt : -dt; + if( rotate ? theta==0 : scale==1 ) break; + float st = sin(theta), ct = cos(theta); + MaskAuto *keyframe = gui->mask_keyframe; + int gang = mask_gui->gang_focus->get_value(); + int k = mwindow->edl->session->cwindow_mask; + int n = gang ? keyframe->masks.size() : k+1; + for( int j=gang? 0 : k; jmask_enables[j]->get_value() ) continue; + SubMask *sub_mask = keyframe->get_submask(j); + if( !sub_mask ) continue; + MaskPoints &points = sub_mask->points; + for( int i=0; ix - gui->x_origin; + float py = point->y - gui->y_origin; + float nx = !rotate ? px*xscale : px*ct + py*st; + float ny = !rotate ? py*yscale : py*ct - px*st; + point->x = nx + gui->x_origin; + point->y = ny + gui->y_origin; + px = point->control_x1; py = point->control_y1; + point->control_x1 = !rotate ? px*xscale : px*ct + py*st; + point->control_y1 = !rotate ? py*yscale : py*ct - px*st; + px = point->control_x2; py = point->control_y2; + point->control_x2 = !rotate ? px*xscale : px*ct + py*st; + point->control_y2 = !rotate ? py*yscale : py*ct - px*st; + } + } + rerender = 1; + redraw = 1; + update_points = 0; + break; } } - if( !EQUIV(last_x, point->x) || + if( !(rerender && redraw) && (!EQUIV(last_x, point->x) || !EQUIV(last_y, point->y) || !EQUIV(last_control_x1, point->control_x1) || !EQUIV(last_control_y1, point->control_y1) || !EQUIV(last_control_x2, point->control_x2) || - !EQUIV(last_control_y2, point->control_y2)) { + !EQUIV(last_control_y2, point->control_y2)) ) { rerender = 1; redraw = 1; } } else - if(gui->current_operation == CWINDOW_NONE) { + if( gui->current_operation == CWINDOW_NONE ) { // printf("CWindowCanvas::do_mask %d\n", __LINE__); int over_point = 0; - for(int i = 0; i < points.size() && !over_point; i++) { + for( int i = 0; i < points.size() && !over_point; i++ ) { MaskPoint *point = points.get(i); float x0 = point->x; float y0 = point->y; @@ -2144,22 +2150,22 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, float canvas_y0 = (y0 - half_track_h) * projector_z + projector_y; output_to_canvas(mwindow->edl, 0, canvas_x0, canvas_y0); - if(test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0)) { + if( test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0) ) { over_point = 1; } - if(!over_point && gui->ctrl_down()) { + if( !over_point && gui->ctrl_down() ) { float canvas_x1 = (x1 - half_track_w) * projector_z + projector_x; float canvas_y1 = (y1 - half_track_h) * projector_z + projector_y; output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1); - if(test_bbox(cursor_x, cursor_y, canvas_x1, canvas_y1)) { + if( test_bbox(cursor_x, cursor_y, canvas_x1, canvas_y1) ) { over_point = 1; } else { float canvas_x2 = (x2 - half_track_w) * projector_z + projector_x; float canvas_y2 = (y2 - half_track_h) * projector_z + projector_y; output_to_canvas(mwindow->edl, 0, canvas_x2, canvas_y2); - if(test_bbox(cursor_x, cursor_y, canvas_x2, canvas_y2)) { + if( test_bbox(cursor_x, cursor_y, canvas_x2, canvas_y2) ) { over_point = 1; } } @@ -2176,23 +2182,71 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, #ifdef USE_KEYFRAME_SPANNING // Must commit change after operation. - if(rerender && track) { + if( rerender && track ) { // Swap EDL keyframe with original. // Apply new values to keyframe span MaskAuto temp_keyframe(mwindow->edl, mask_autos); temp_keyframe.copy_data(gui->mask_keyframe); // Apply interpolated points back to keyframe - temp_keyframe.set_points(&points, mwindow->edl->session->cwindow_mask); + if( update_points ) + temp_keyframe.set_points(&points, mwindow->edl->session->cwindow_mask); gui->mask_keyframe->copy_data(gui->orig_mask_keyframe); mask_autos->update_parameter(&temp_keyframe); } #endif - - points.remove_all_objects(); //printf("CWindowCanvas::do_mask 20\n"); + + if( draw && draw_boundary && !draw_markers ) { + BC_WindowBase *cvs_win = get_canvas(); + cvs_win->set_inverse(); + cvs_win->set_color(RED+GREEN); + for( int k=0; kedl->session->cwindow_mask ) continue; + points.remove_all_objects(); + if( use_interpolated ) + mask_autos->get_points(&points, k, position, PLAY_FORWARD); + else + prev_mask->get_points(&points, k); + MaskEdge edge; + edge.load(points, 0); + for( int i=0; iedl, 0, ax, ay); + output_to_canvas(mwindow->edl, 0, bx, by); + cvs_win->draw_line(ax,ay, bx,by); + } + } + } + return result; } +int CWindowCanvas::do_mask_focus() +{ + Track *track = gui->cwindow->calculate_affected_track(); + int64_t position = track->to_units( + mwindow->edl->local_session->get_selectionstart(1), + 0); + float projector_x, projector_y, projector_z; + track->automation->get_projector( + &projector_x, &projector_y, &projector_z, + position, PLAY_FORWARD); + float cx = get_cursor_x(), cy = get_cursor_y(); + canvas_to_output(mwindow->edl, 0, cx, cy); + projector_x += mwindow->edl->session->output_w / 2; + projector_y += mwindow->edl->session->output_h / 2; + float half_track_w = (float)track->track_w / 2; + float half_track_h = (float)track->track_h / 2; + cx = (cx - projector_x) / projector_z + half_track_w; + cy = (cy - projector_y) / projector_z + half_track_h; + CWindowMaskGUI *mask_gui = (CWindowMaskGUI*) gui->tool_panel->tool_gui; + mask_gui->set_focused(1, cx, cy); + return 1; +} + int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) { int result = 0; @@ -2204,11 +2258,9 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) - if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) - { + if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) { - if(draw) - { + if( draw ) { row1 = gui->eyedrop_y - radius; row2 = gui->eyedrop_y + radius; column1 = gui->eyedrop_x - radius; @@ -2219,8 +2271,8 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) CLAMP(column1, 0, refresh_frame->get_w() - 1); CLAMP(column2, 0, refresh_frame->get_w() - 1); - if(row2 <= row1) row2 = row1 + 1; - if(column2 <= column1) column2 = column1 + 1; + if( row2 <= row1 ) row2 = row1 + 1; + if( column2 <= column1 ) column2 = column1 + 1; float x1 = column1; float y1 = row1; @@ -2231,8 +2283,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) output_to_canvas(mwindow->edl, 0, x2, y2); //printf("CWindowCanvas::do_eyedrop %d %f %f %f %f\n", __LINE__, x1, x2, y1, y2); - if(x2 - x1 >= 1 && y2 - y1 >= 1) - { + if( x2 - x1 >= 1 && y2 - y1 >= 1 ) { get_canvas()->set_inverse(); get_canvas()->set_color(WHITE); @@ -2248,20 +2299,17 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) } } - if(button_press) - { + if( button_press ) { gui->current_operation = CWINDOW_EYEDROP; gui->tool_panel->raise_window(); } - if(gui->current_operation == CWINDOW_EYEDROP) - { + if( gui->current_operation == CWINDOW_EYEDROP ) { mwindow->undo->update_undo_before(_("Eyedrop"), this); // Get color out of frame. // Doesn't work during playback because that bypasses the refresh frame. - if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) - { + if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) { float cursor_x = get_cursor_x(); float cursor_y = get_cursor_y(); canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y); @@ -2276,13 +2324,12 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) CLAMP(row2, 0, refresh_frame->get_h() - 1); CLAMP(column1, 0, refresh_frame->get_w() - 1); CLAMP(column2, 0, refresh_frame->get_w() - 1); - if(row2 <= row1) row2 = row1 + 1; - if(column2 <= column1) column2 = column1 + 1; + if( row2 <= row1 ) row2 = row1 + 1; + if( column2 <= column1 ) column2 = column1 + 1; // hide it - if(gui->eyedrop_visible) - { + if( gui->eyedrop_visible ) { int temp; do_eyedrop(temp, 0, 1); gui->eyedrop_visible = 0; @@ -2312,7 +2359,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) float red = (float)*row++ / max; \ float green = (float)*row++ / max; \ float blue = (float)*row++ / max; \ - if(do_yuv) \ + if( do_yuv ) \ { \ float r = red + V_TO_R * (blue - 0.5); \ float g = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \ @@ -2320,18 +2367,18 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) mwindow->edl->local_session->red += r; \ mwindow->edl->local_session->green += g; \ mwindow->edl->local_session->blue += b; \ - if(r > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = r; \ - if(g > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = g; \ - if(b > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = b; \ + if( r > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = r; \ + if( g > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = g; \ + if( b > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = b; \ } \ else \ { \ mwindow->edl->local_session->red += red; \ mwindow->edl->local_session->green += green; \ mwindow->edl->local_session->blue += blue; \ - if(red > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = red; \ - if(green > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = green; \ - if(blue > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = blue; \ + if( red > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = red; \ + if( green > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = green; \ + if( blue > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = blue; \ } \ } @@ -2343,11 +2390,9 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) mwindow->edl->local_session->red_max = 0; mwindow->edl->local_session->green_max = 0; mwindow->edl->local_session->blue_max = 0; - for(int i = row1; i < row2; i++) - { - for(int j = column1; j < column2; j++) - { - switch(refresh_frame->get_color_model()) + for( int i = row1; i < row2; i++ ) { + for( int j = column1; j < column2; j++ ) { + switch( refresh_frame->get_color_model() ) { case BC_YUV888: GET_COLOR(unsigned char, 3, 0xff, 1); @@ -2382,8 +2427,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) mwindow->edl->local_session->blue /= (row2 - row1) * (column2 - column1); } - else - { + else { mwindow->edl->local_session->red = 0; mwindow->edl->local_session->green = 0; mwindow->edl->local_session->blue = 0; @@ -2425,13 +2469,11 @@ int CWindowCanvas::need_overlays() void CWindowCanvas::draw_overlays() { - if(mwindow->edl->session->safe_regions) - { + if( mwindow->edl->session->safe_regions ) { draw_safe_regions(); } - if(mwindow->edl->session->cwindow_scrollbars) - { + if( mwindow->edl->session->cwindow_scrollbars ) { // Always draw output rectangle float x1, y1, x2, y2; x1 = 0; @@ -2443,17 +2485,12 @@ void CWindowCanvas::draw_overlays() get_canvas()->set_inverse(); get_canvas()->set_color(WHITE); - - get_canvas()->draw_rectangle((int)x1, - (int)y1, - (int)(x2 - x1), - (int)(y2 - y1)); - + int ix1 = x1-1, iy1 = y1-1, ix2 = x2+1, iy2 = y2+1; + get_canvas()->draw_rectangle(ix1, iy1, ix2-ix1, iy2-iy1); get_canvas()->set_opaque(); } - if(gui->highlighted) - { + if( gui->highlighted ) { get_canvas()->set_color(WHITE); get_canvas()->set_inverse(); get_canvas()->draw_rectangle(0, 0, get_canvas()->get_w(), get_canvas()->get_h()); @@ -2463,14 +2500,14 @@ void CWindowCanvas::draw_overlays() int temp1 = 0, temp2 = 0; //printf("CWindowCanvas::draw_overlays 1 %d\n", mwindow->edl->session->cwindow_operation); - switch(mwindow->edl->session->cwindow_operation) + switch( mwindow->edl->session->cwindow_operation ) { case CWINDOW_CAMERA: - draw_bezier(1); + draw_outlines(1); break; case CWINDOW_PROJECTOR: - draw_bezier(0); + draw_outlines(0); break; case CWINDOW_CROP: @@ -2486,8 +2523,7 @@ void CWindowCanvas::draw_overlays() break; case CWINDOW_EYEDROP: - if(gui->eyedrop_visible) - { + if( gui->eyedrop_visible ) { int rerender; do_eyedrop(rerender, 0, 1); gui->eyedrop_visible = 1; @@ -2608,38 +2644,33 @@ int CWindowCanvas::test_crop(int button_press, int &redraw) output_to_canvas(mwindow->edl, 0, canvas_x2, canvas_y2); - if(gui->current_operation == CWINDOW_CROP) - { + if( gui->current_operation == CWINDOW_CROP ) { handle_selected = gui->crop_handle; } else - if(canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W && - canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H) - { + if( canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W && + canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H ) { handle_selected = 0; gui->crop_origin_x = x1; gui->crop_origin_y = y1; } else - if(canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 && - canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H) - { + if( canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 && + canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H ) { handle_selected = 1; gui->crop_origin_x = x2; gui->crop_origin_y = y1; } else - if(canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W && - canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2) - { + if( canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W && + canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2 ) { handle_selected = 2; gui->crop_origin_x = x1; gui->crop_origin_y = y2; } else - if(canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 && - canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2) - { + if( canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 && + canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2 ) { handle_selected = 3; gui->crop_origin_x = x2; gui->crop_origin_y = y2; @@ -2656,10 +2687,8 @@ int CWindowCanvas::test_crop(int button_press, int &redraw) // handle_selected); // Start dragging. - if(button_press) - { - if(gui->alt_down()) - { + if( button_press ) { + if( gui->alt_down() ) { gui->crop_translate = 1; gui->crop_origin_x1 = x1; gui->crop_origin_y1 = y1; @@ -2676,8 +2705,7 @@ int CWindowCanvas::test_crop(int button_press, int &redraw) gui->tool_panel->raise_window(); result = 1; - if(handle_selected < 0 && !gui->crop_translate) - { + if( handle_selected < 0 && !gui->crop_translate ) { x2 = x1 = cursor_x; y2 = y1 = cursor_y; mwindow->edl->session->crop_x1 = (int)x1; @@ -2689,8 +2717,7 @@ int CWindowCanvas::test_crop(int button_press, int &redraw) } else // Translate all 4 points - if(gui->current_operation == CWINDOW_CROP && gui->crop_translate) - { + if( gui->current_operation == CWINDOW_CROP && gui->crop_translate ) { x1 = cursor_x - gui->x_origin + gui->crop_origin_x1; y1 = cursor_y - gui->y_origin + gui->crop_origin_y1; x2 = cursor_x - gui->x_origin + gui->crop_origin_x2; @@ -2705,40 +2732,32 @@ int CWindowCanvas::test_crop(int button_press, int &redraw) } else // Update dragging - if(gui->current_operation == CWINDOW_CROP) - { - switch(gui->crop_handle) - { - case -1: - x1 = gui->crop_origin_x; - y1 = gui->crop_origin_y; - x2 = gui->crop_origin_x; - y2 = gui->crop_origin_y; - if(cursor_x < gui->x_origin) - { - if(cursor_y < gui->y_origin) - { + if( gui->current_operation == CWINDOW_CROP ) { + switch( gui->crop_handle ) { + case -1: + x1 = gui->crop_origin_x; + y1 = gui->crop_origin_y; + x2 = gui->crop_origin_x; + y2 = gui->crop_origin_y; + if( cursor_x < gui->x_origin ) { + if( cursor_y < gui->y_origin ) { x1 = cursor_x; y1 = cursor_y; } else - if(cursor_y >= gui->y_origin) - { + if( cursor_y >= gui->y_origin ) { x1 = cursor_x; y2 = cursor_y; } } else - if(cursor_x >= gui->x_origin) - { - if(cursor_y < gui->y_origin) - { + if( cursor_x >= gui->x_origin ) { + if( cursor_y < gui->y_origin ) { y1 = cursor_y; x2 = cursor_x; } else - if(cursor_y >= gui->y_origin) - { + if( cursor_y >= gui->y_origin ) { x2 = cursor_x; y2 = cursor_y; } @@ -2768,38 +2787,33 @@ int CWindowCanvas::test_crop(int button_press, int &redraw) break; } - if(!EQUIV(mwindow->edl->session->crop_x1, x1) || + if( !EQUIV(mwindow->edl->session->crop_x1, x1) || !EQUIV(mwindow->edl->session->crop_x2, x2) || !EQUIV(mwindow->edl->session->crop_y1, y1) || - !EQUIV(mwindow->edl->session->crop_y2, y2)) - { - if (x1 > x2) - { + !EQUIV(mwindow->edl->session->crop_y2, y2) ) { + if( x1 > x2 ) { float tmp = x1; x1 = x2; x2 = tmp; - switch (gui->crop_handle) - { - case 0: gui->crop_handle = 1; break; - case 1: gui->crop_handle = 0; break; - case 2: gui->crop_handle = 3; break; - case 3: gui->crop_handle = 2; break; - default: break; + switch( gui->crop_handle ) { + case 0: gui->crop_handle = 1; break; + case 1: gui->crop_handle = 0; break; + case 2: gui->crop_handle = 3; break; + case 3: gui->crop_handle = 2; break; + default: break; } } - if (y1 > y2) - { + if( y1 > y2 ) { float tmp = y1; y1 = y2; y2 = tmp; - switch (gui->crop_handle) - { - case 0: gui->crop_handle = 2; break; - case 1: gui->crop_handle = 3; break; - case 2: gui->crop_handle = 0; break; - case 3: gui->crop_handle = 1; break; - default: break; + switch( gui->crop_handle ) { + case 0: gui->crop_handle = 2; break; + case 1: gui->crop_handle = 3; break; + case 2: gui->crop_handle = 0; break; + case 3: gui->crop_handle = 1; break; + default: break; } } @@ -2813,33 +2827,21 @@ int CWindowCanvas::test_crop(int button_press, int &redraw) } else // Update cursor font - if(handle_selected >= 0) - { - switch(handle_selected) - { - case 0: - set_cursor(UPLEFT_RESIZE); - break; - case 1: - set_cursor(UPRIGHT_RESIZE); - break; - case 2: - set_cursor(DOWNLEFT_RESIZE); - break; - case 3: - set_cursor(DOWNRIGHT_RESIZE); - break; + if( handle_selected >= 0 ) { + switch( handle_selected ) { + case 0: set_cursor(UPLEFT_RESIZE); break; + case 1: set_cursor(UPRIGHT_RESIZE); break; + case 2: set_cursor(DOWNLEFT_RESIZE); break; + case 3: set_cursor(DOWNRIGHT_RESIZE); break; } result = 1; } - else - { + else { set_cursor(ARROW_CURSOR); } #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x)))) - if(redraw) - { + if( redraw ) { CLAMP(mwindow->edl->session->crop_x1, 0, mwindow->edl->session->output_w); CLAMP(mwindow->edl->session->crop_x2, 0, mwindow->edl->session->output_w); CLAMP(mwindow->edl->session->crop_y1, 0, mwindow->edl->session->output_h); @@ -2867,7 +2869,7 @@ void CWindowCanvas::draw_crop() output_to_canvas(mwindow->edl, 0, x1, y1); output_to_canvas(mwindow->edl, 0, x2, y2); - if(x2 - x1 && y2 - y1) + if( x2 - x1 && y2 - y1 ) get_canvas()->draw_rectangle((int)x1, (int)y1, (int)(x2 - x1), @@ -2881,74 +2883,58 @@ void CWindowCanvas::draw_crop() } - - - - - - -void CWindowCanvas::draw_bezier(int do_camera) +void CWindowCanvas::draw_outlines(int do_camera) { Track *track = gui->cwindow->calculate_affected_track(); - if(!track) return; + if( !track ) return; - float center_x; - float center_y; - float center_z; + float proj_x, proj_y, proj_z; int64_t position = track->to_units( mwindow->edl->local_session->get_selectionstart(1), 0); - if( do_camera ) { - track->automation->get_camera(¢er_x, - ¢er_y, ¢er_z, position, PLAY_FORWARD); -// follow image, not camera - center_x = -center_x; center_y = -center_y; - } - else - track->automation->get_projector(¢er_x, - ¢er_y, ¢er_z, position, PLAY_FORWARD); - -// center_x += track->track_w / 2; -// center_y += track->track_h / 2; - center_x += mwindow->edl->session->output_w / 2; - center_y += mwindow->edl->session->output_h / 2; - float track_x1 = center_x - track->track_w / 2 * center_z; - float track_y1 = center_y - track->track_h / 2 * center_z; - float track_x2 = track_x1 + track->track_w * center_z; - float track_y2 = track_y1 + track->track_h * center_z; - - output_to_canvas(mwindow->edl, 0, track_x1, track_y1); - output_to_canvas(mwindow->edl, 0, track_x2, track_y2); + track->automation->get_projector(&proj_x, &proj_y, &proj_z, + position, PLAY_FORWARD); + + proj_x += mwindow->edl->session->output_w/2.; + proj_y += mwindow->edl->session->output_h/2.; + float proj_x1 = proj_x - track->track_w/2. * proj_z; + float proj_y1 = proj_y - track->track_h/2. * proj_z; + float proj_x2 = proj_x + track->track_w/2. * proj_z; + float proj_y2 = proj_y + track->track_h/2. * proj_z; + float x1 = proj_x1, x2 = proj_x2; + float y1 = proj_y1, y2 = proj_y2; + output_to_canvas(mwindow->edl, 0, x1, y1); + output_to_canvas(mwindow->edl, 0, x2, y2); #define DRAW_PROJECTION(offset) \ - get_canvas()->draw_rectangle((int)track_x1 + offset, \ - (int)track_y1 + offset, \ - (int)(track_x2 - track_x1), \ - (int)(track_y2 - track_y1)); \ - get_canvas()->draw_line((int)track_x1 + offset, \ - (int)track_y1 + offset, \ - (int)track_x2 + offset, \ - (int)track_y2 + offset); \ - get_canvas()->draw_line((int)track_x2 + offset, \ - (int)track_y1 + offset, \ - (int)track_x1 + offset, \ - (int)track_y2 + offset); \ - + get_canvas()->draw_rectangle(x1+offset, y1+offset, (x2-x1), (y2-y1)); \ + get_canvas()->draw_line(x1+offset, y1+offset, x2+offset, y2+offset); \ + get_canvas()->draw_line(x2+offset, y1+offset, x1+offset, y2+offset); \ // Drop shadow get_canvas()->set_color(BLACK); DRAW_PROJECTION(1); - -// canvas->set_inverse(); - if(do_camera) - get_canvas()->set_color(GREEN); - else - get_canvas()->set_color(RED); - + get_canvas()->set_color(do_camera ? GREEN : RED); DRAW_PROJECTION(0); -// canvas->set_opaque(); + if( do_camera ) { + float cam_x, cam_y, cam_z; + track->automation->get_camera(&cam_x, &cam_y, &cam_z, + position, PLAY_FORWARD); + cam_x += track->track_w / 2.; + cam_y += track->track_h / 2.; +// follow image, not camera + cam_x = -cam_x; cam_y = -cam_y; cam_z *= proj_z; + float cam_x1 = cam_x * cam_z + proj_x; + float cam_y1 = cam_y * cam_z + proj_y; + float cam_x2 = (cam_x + track->track_w) * cam_z + proj_x; + float cam_y2 = (cam_y + track->track_h) * cam_z + proj_y; + output_to_canvas(mwindow->edl, 0, cam_x1, cam_y1); + output_to_canvas(mwindow->edl, 0, cam_x2, cam_y2); + get_canvas()->set_color(YELLOW); + get_canvas()->draw_rectangle(cam_x1, cam_y1, cam_x2-cam_x1, cam_y2-cam_y1); + } } int CWindowCanvas::test_bezier(int button_press, @@ -2961,114 +2947,71 @@ int CWindowCanvas::test_bezier(int button_press, // Processing drag operation. // Create keyframe during first cursor motion. - if(!button_press) - { + if( !button_press ) { float cursor_x = get_cursor_x(); float cursor_y = get_cursor_y(); canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y); - if(gui->current_operation == CWINDOW_CAMERA || - gui->current_operation == CWINDOW_PROJECTOR) - { - if(!gui->ctrl_down() && gui->shift_down() && !gui->translating_zoom) - { + if( gui->current_operation == CWINDOW_CAMERA || + gui->current_operation == CWINDOW_PROJECTOR ) { + if( !gui->ctrl_down() && gui->shift_down() && !gui->translating_zoom ) { gui->translating_zoom = 1; gui->reset_affected(); } - else - if(!gui->ctrl_down() && !gui->shift_down() && gui->translating_zoom) - { + else if( !gui->ctrl_down() && !gui->shift_down() && gui->translating_zoom ) { gui->translating_zoom = 0; gui->reset_affected(); } // Get target keyframe - float last_center_x; - float last_center_y; - float last_center_z; - int created; - - if(!gui->affected_x && !gui->affected_y && !gui->affected_z) - { - FloatAutos *affected_x_autos; - FloatAutos *affected_y_autos; - FloatAutos *affected_z_autos; - if(!gui->affected_track) return 0; + if( !gui->affected_x && !gui->affected_y && !gui->affected_z ) { + if( !gui->affected_track ) return 0; + FloatAutos *affected_x_autos, *affected_y_autos, *affected_z_autos; + FloatAutos** autos = (FloatAutos**) gui->affected_track->automation->autos; + if( mwindow->edl->session->cwindow_operation == CWINDOW_CAMERA ) { + affected_x_autos = autos[AUTOMATION_CAMERA_X]; + affected_y_autos = autos[AUTOMATION_CAMERA_Y]; + affected_z_autos = autos[AUTOMATION_CAMERA_Z]; + } + else { + affected_x_autos = autos[AUTOMATION_PROJECTOR_X]; + affected_y_autos = autos[AUTOMATION_PROJECTOR_Y]; + affected_z_autos = autos[AUTOMATION_PROJECTOR_Z]; + } double position = mwindow->edl->local_session->get_selectionstart(1); int64_t track_position = gui->affected_track->to_units(position, 0); - - if(mwindow->edl->session->cwindow_operation == CWINDOW_CAMERA) - { - affected_x_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_X]; - affected_y_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_Y]; - affected_z_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_Z]; - } - else - { - affected_x_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_X]; - affected_y_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_Y]; - affected_z_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_Z]; + FloatAuto *prev_x = 0, *next_x = 0; + float new_x = affected_x_autos->get_value(track_position, PLAY_FORWARD, prev_x, next_x); + FloatAuto *prev_y = 0, *next_y = 0; + float new_y = affected_y_autos->get_value(track_position, PLAY_FORWARD, prev_y, next_y); + FloatAuto *prev_z = 0, *next_z = 0; + float new_z = affected_z_autos->get_value(track_position, PLAY_FORWARD, prev_z, next_z); + int zooming = gui->translating_zoom, created; + gui->affected_x = (FloatAuto*)gui->cwindow->calculate_affected_auto( + affected_x_autos, !zooming, &created, 0); + if( created ) { + gui->affected_x->set_value(new_x); + redraw_canvas = 1; } - - - if(gui->translating_zoom) - { - FloatAuto *previous = 0; - FloatAuto *next = 0; - float new_z = affected_z_autos->get_value( - track_position, - PLAY_FORWARD, - previous, - next); - gui->affected_z = - (FloatAuto*)gui->cwindow->calculate_affected_auto( - affected_z_autos, 1, &created, 0); - if(created) { - gui->affected_z->set_value(new_z); - redraw_canvas = 1; - } + gui->affected_y = (FloatAuto*)gui->cwindow->calculate_affected_auto( + affected_y_autos, !zooming, &created, 0); + if( created ) { + gui->affected_y->set_value(new_y); + redraw_canvas = 1; } - else - { - FloatAuto *previous = 0; - FloatAuto *next = 0; - float new_x = affected_x_autos->get_value( - track_position, - PLAY_FORWARD, - previous, - next); - previous = 0; - next = 0; - float new_y = affected_y_autos->get_value( - track_position, - PLAY_FORWARD, - previous, - next); - gui->affected_x = - (FloatAuto*)gui->cwindow->calculate_affected_auto( - affected_x_autos, 1, &created, 0); - if(created) { - gui->affected_x->set_value(new_x); - redraw_canvas = 1; - } - gui->affected_y = - (FloatAuto*)gui->cwindow->calculate_affected_auto( - affected_y_autos, 1, &created, 0); - if(created) { - gui->affected_y->set_value(new_y); - redraw_canvas = 1; - } + gui->affected_z = (FloatAuto*)gui->cwindow->calculate_affected_auto( + affected_z_autos, zooming, &created, 0); + if( created ) { + gui->affected_z->set_value(new_z); + redraw_canvas = 1; } - calculate_origin(); - if(gui->translating_zoom) - { + if( gui->translating_zoom ) { gui->center_z = gui->affected_z->get_value(); } - else - { + else { gui->center_x = gui->affected_x->get_value(); gui->center_y = gui->affected_y->get_value(); } @@ -3077,41 +3020,36 @@ int CWindowCanvas::test_bezier(int button_press, redraw = 1; } - if(gui->translating_zoom) - { - last_center_z = gui->affected_z->get_value(); - float z = gui->center_z + (cursor_y - gui->y_origin) / 128; + float x_val = gui->affected_x->get_value(); + float y_val = gui->affected_y->get_value(); + float z_val = gui->affected_z->get_value(); + + if( gui->translating_zoom ) { + float z = gui->center_z + (cursor_y - gui->y_origin) / yS(128); if( z < 0 ) z = 0; - if(!EQUIV(last_center_z, z)) - { + if( !EQUIV(z_val, z) ) { rerender = 1; redraw = 1; redraw_canvas = 1; } gui->affected_z->set_value(z); } - else - { - last_center_x = gui->affected_x->get_value(); - last_center_y = gui->affected_y->get_value(); + else { float dx = cursor_x - gui->x_origin; float dy = cursor_y - gui->y_origin; // follow image, not camera - if(gui->current_operation == CWINDOW_CAMERA ) { - dx = -dx; dy = -dy; + if( gui->current_operation == CWINDOW_CAMERA ) { + dx = -dx / z_val; dy = -dy / z_val; } float x = gui->center_x + dx; float y = gui->center_y + dy; gui->affected_x->set_value(x); gui->affected_y->set_value(y); - if( !EQUIV(last_center_x, x) || !EQUIV(last_center_y, y) ) - { + if( !EQUIV(x_val, x) || !EQUIV(y_val, y) ) { rerender = 1; redraw = 1; redraw_canvas = 1; } - gui->affected_x->set_value(x); - gui->affected_y->set_value(y); } } @@ -3126,8 +3064,7 @@ int CWindowCanvas::test_bezier(int button_press, gui->affected_track = gui->cwindow->calculate_affected_track(); gui->reset_affected(); - if(gui->affected_track) - { + if( gui->affected_track ) { if( do_camera ) mwindow->undo->update_undo_before(_("camera"), this); else @@ -3143,65 +3080,60 @@ int CWindowCanvas::test_bezier(int button_press, return result; } - int CWindowCanvas::test_zoom(int &redraw) { - int result = 0; - float x, y; float zoom = 0; - - if( mwindow->edl->session->cwindow_scrollbars ) { - if( *gui->zoom_panel->get_text() != 'x' ) { -// Find current zoom in table - int idx = total_zooms; float old_zoom = get_zoom(); - while( --idx >= 0 && !EQUIV(my_zoom_table[idx], old_zoom) ); - if( idx >= 0 ) { - idx += get_buttonpress() == 5 || - gui->ctrl_down() || gui->shift_down() ? -1 : +1 ; - CLAMP(idx, 0, total_zooms-1); - zoom = my_zoom_table[idx]; - } + int button = get_buttonpress(); + if( button == LEFT_BUTTON ) + button = gui->shift_down() ? WHEEL_DOWN : WHEEL_UP; + if( !(zoom = get_zoom()) ) + zoom = get_auto_zoom(mwindow->edl); + switch( button ) { + case WHEEL_UP: { + int idx = 0; + for( ; idx < total_zooms; ++idx ) { + if( EQUIV(zoom, my_zoom_table[idx]) ) continue; + if( zoom < my_zoom_table[idx] ) break; } - x = get_cursor_x(); y = get_cursor_y(); - if( !zoom ) { - mwindow->edl->session->cwindow_scrollbars = 0; - gui->zoom_panel->update(0); - zoom = gui->get_auto_zoom(); + float zoom11 = 1.1f * zoom; + zoom = idx < total_zooms ? my_zoom_table[idx] : zoom11; + if( zoom > zoom11 ) zoom = zoom11; + break; } + case WHEEL_DOWN: { + int idx = total_zooms; + for( ; --idx >= 0; ) { + if( EQUIV(my_zoom_table[idx], zoom) ) continue; + if( my_zoom_table[idx] < zoom ) break; } - else { - gui->zoom_panel->ZoomPanel::update(zoom); - float output_x = x, output_y = y; - canvas_to_output(mwindow->edl, 0, output_x, output_y); - x = output_x - x / zoom; - y = output_y - y / zoom; + float zoom09 = 0.9f * zoom; + zoom = idx >= 0 ? my_zoom_table[idx] : zoom09; + if( zoom < zoom09 ) zoom = zoom09; + break; } + case MIDDLE_BUTTON: + if( gui->shift_down() ) { + zoom = 0; + break; } - } - else { - mwindow->edl->session->cwindow_scrollbars = 1; - x = (mwindow->edl->session->output_w - w) / 2; - y = (mwindow->edl->session->output_h - h) / 2; - zoom = 1; - } - update_zoom((int)x, (int)y, zoom); - - gui->composite_panel->cpanel_zoom->update(zoom); - - reposition_window(mwindow->edl, - mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y, - mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h); - redraw = 1; result = 1; - - return result; + default: // fall thru + return 0; + } + float cx = get_cursor_x(), cy = get_cursor_y(); + set_zoom(mwindow->edl, zoom, cx, cy); + gui->zoom_panel->update(zoom); + gui->update_canvas(); + redraw = 1; + return 1; } void CWindowCanvas::calculate_origin() { - gui->x_origin = get_cursor_x(); - gui->y_origin = get_cursor_y(); -//printf("CWindowCanvas::calculate_origin 1 %f %f\n", gui->x_origin, gui->y_origin); - canvas_to_output(mwindow->edl, 0, gui->x_origin, gui->y_origin); -//printf("CWindowCanvas::calculate_origin 2 %f %f\n", gui->x_origin, gui->y_origin); + float zoom_x, zoom_y, conformed_w, conformed_h; + get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h); + gui->x_offset = get_x_offset(mwindow->edl, 0, zoom_x, conformed_w, conformed_h); + gui->y_offset = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h); + gui->x_origin = (float)get_cursor_x() / zoom_x + gui->x_offset; + gui->y_origin = (float)get_cursor_y() / zoom_y + gui->y_offset; } @@ -3214,28 +3146,27 @@ int CWindowCanvas::cursor_leave_event() int CWindowCanvas::cursor_enter_event() { int redraw = 0; - switch(mwindow->edl->session->cwindow_operation) - { - case CWINDOW_CAMERA: - case CWINDOW_PROJECTOR: - set_cursor(MOVE_CURSOR); - break; - case CWINDOW_ZOOM: - set_cursor(MOVE_CURSOR); - break; - case CWINDOW_CROP: - test_crop(0, redraw); - break; - case CWINDOW_PROTECT: - set_cursor(ARROW_CURSOR); - break; - case CWINDOW_MASK: - case CWINDOW_RULER: - set_cursor(CROSS_CURSOR); - break; - case CWINDOW_EYEDROP: - set_cursor(CROSS_CURSOR); - break; + switch( mwindow->edl->session->cwindow_operation ) { + case CWINDOW_CAMERA: + case CWINDOW_PROJECTOR: + set_cursor(MOVE_CURSOR); + break; + case CWINDOW_ZOOM: + set_cursor(MOVE_CURSOR); + break; + case CWINDOW_CROP: + test_crop(0, redraw); + break; + case CWINDOW_PROTECT: + set_cursor(ARROW_CURSOR); + break; + case CWINDOW_MASK: + case CWINDOW_RULER: + set_cursor(CROSS_CURSOR); + break; + case CWINDOW_EYEDROP: + set_cursor(CROSS_CURSOR); + break; } return 1; } @@ -3246,97 +3177,59 @@ int CWindowCanvas::cursor_motion_event() //printf("CWindowCanvas::cursor_motion_event %d current_operation=%d\n", __LINE__, gui->current_operation); - switch(gui->current_operation) - { - case CWINDOW_SCROLL: - { - float zoom = get_zoom(); - float cursor_x = get_cursor_x(); - float cursor_y = get_cursor_y(); - - float zoom_x, zoom_y, conformed_w, conformed_h; - get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h); - cursor_x = (float)cursor_x / zoom_x + gui->x_offset; - cursor_y = (float)cursor_y / zoom_y + gui->y_offset; + switch( gui->current_operation ) { + case CWINDOW_SCROLL: { + result = do_scroll(mwindow->edl, get_cursor_x(), get_cursor_y()); + break; } + case CWINDOW_RULER: + result = do_ruler(0, 1, 0, 0); + break; + case CWINDOW_CAMERA: + result = test_bezier(0, redraw, redraw_canvas, rerender, 1); + break; - int x = (int)(gui->x_origin - cursor_x + gui->x_offset); - int y = (int)(gui->y_origin - cursor_y + gui->y_offset); + case CWINDOW_PROJECTOR: + result = test_bezier(0, redraw, redraw_canvas, rerender, 0); + break; - update_zoom(x, - y, - zoom); - update_scrollbars(0); - redraw = 1; - result = 1; - break; - } + case CWINDOW_CROP: + result = test_crop(0, redraw); +// printf("CWindowCanvas::cursor_motion_event %d result=%d redraw=%d\n", +// __LINE__, result, redraw); + break; - case CWINDOW_RULER: - result = do_ruler(0, 1, 0, 0); - break; + case CWINDOW_MASK: + case CWINDOW_MASK_CONTROL_IN: + case CWINDOW_MASK_CONTROL_OUT: + case CWINDOW_MASK_TRANSLATE: + result = do_mask(redraw, rerender, 0, 1, 0); + break; - case CWINDOW_CAMERA: - result = test_bezier(0, redraw, redraw_canvas, rerender, 1); - break; + case CWINDOW_EYEDROP: + result = do_eyedrop(rerender, 0, 0); + break; - case CWINDOW_PROJECTOR: - result = test_bezier(0, redraw, redraw_canvas, rerender, 0); - break; + default: + break; + } +// cursor font changes + if( !result ) { +// printf("CWindowCanvas::cursor_motion_event %d cwindow_operation=%d\n", +// __LINE__, mwindow->edl->session->cwindow_operation); + switch( mwindow->edl->session->cwindow_operation ) { case CWINDOW_CROP: result = test_crop(0, redraw); -// printf("CWindowCanvas::cursor_motion_event %d result=%d redraw=%d\n", -// __LINE__, -// result, -// redraw); - break; - - case CWINDOW_MASK: - case CWINDOW_MASK_CONTROL_IN: - case CWINDOW_MASK_CONTROL_OUT: - case CWINDOW_MASK_TRANSLATE: - - result = do_mask(redraw, - rerender, - 0, - 1, - 0); break; - - case CWINDOW_EYEDROP: - result = do_eyedrop(rerender, 0, 0); + case CWINDOW_RULER: + result = do_ruler(0, 1, 0, 0); break; - - default: + case CWINDOW_MASK: + result = do_mask(redraw, rerender, 0, 1, 0); break; - - } - - -// cursor font changes - if(!result) - { -// printf("CWindowCanvas::cursor_motion_event %d cwindow_operation=%d\n", -// __LINE__, -// mwindow->edl->session->cwindow_operation); - switch(mwindow->edl->session->cwindow_operation) - { - case CWINDOW_CROP: - result = test_crop(0, redraw); - break; - case CWINDOW_RULER: - result = do_ruler(0, 1, 0, 0); - break; - case CWINDOW_MASK: - result = do_mask(redraw, - rerender, - 0, - 1, - 0); - break; } } @@ -3353,58 +3246,60 @@ int CWindowCanvas::button_press_event() int redraw_canvas = 0; int rerender = 0; - if(Canvas::button_press_event()) return 1; + if( Canvas::button_press_event() ) return 1; gui->translating_zoom = gui->shift_down(); - calculate_origin(); -//printf("CWindowCanvas::button_press_event 2 %f %f\n", gui->x_origin, gui->y_origin, gui->x_origin, gui->y_origin); - - float zoom_x, zoom_y, conformed_w, conformed_h; - get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h); - gui->x_offset = get_x_offset(mwindow->edl, 0, zoom_x, conformed_w, conformed_h); - gui->y_offset = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h); // Scroll view if( mwindow->edl->session->cwindow_operation != CWINDOW_PROTECT && - get_buttonpress() == 2 ) - { + get_buttonpress() == MIDDLE_BUTTON && !get_canvas()->shift_down() ) { gui->current_operation = CWINDOW_SCROLL; result = 1; } - else + else { // Adjust parameter - { - switch(mwindow->edl->session->cwindow_operation) - { - case CWINDOW_RULER: - result = do_ruler(0, 0, 1, 0); - break; + switch( mwindow->edl->session->cwindow_operation ) { + case CWINDOW_RULER: + result = do_ruler(0, 0, 1, 0); + break; - case CWINDOW_CAMERA: - result = test_bezier(1, redraw, redraw_canvas, rerender, 1); - break; + case CWINDOW_CAMERA: + result = test_bezier(1, redraw, redraw_canvas, rerender, 1); + break; - case CWINDOW_PROJECTOR: - result = test_bezier(1, redraw, redraw_canvas, rerender, 0); - break; + case CWINDOW_PROJECTOR: + result = test_bezier(1, redraw, redraw_canvas, rerender, 0); + break; - case CWINDOW_ZOOM: - result = test_zoom(redraw); - break; + case CWINDOW_ZOOM: + result = test_zoom(redraw); + break; - case CWINDOW_CROP: - result = test_crop(1, redraw); - break; + case CWINDOW_CROP: + result = test_crop(1, redraw); + break; - case CWINDOW_MASK: - if(get_buttonpress() == 1) - result = do_mask(redraw, rerender, 1, 0, 0); + case CWINDOW_MASK: + switch( get_buttonpress() ) { + case LEFT_BUTTON: + result = do_mask(redraw, rerender, 1, 0, 0); break; - - case CWINDOW_EYEDROP: - result = do_eyedrop(rerender, 1, 0); + case MIDDLE_BUTTON: { // && shift_down() + result = do_mask_focus(); + redraw = redraw_canvas = 1; + break; } + case WHEEL_UP: + case WHEEL_DOWN: + result = do_mask(redraw, rerender, 1, 1, 0); break; + } + if( result ) redraw_canvas = 1; + break; + + case CWINDOW_EYEDROP: + result = do_eyedrop(rerender, 1, 0); + break; } } @@ -3417,38 +3312,48 @@ int CWindowCanvas::button_press_event() int CWindowCanvas::button_release_event() { int result = 0; + const char *undo_label = 0; - switch(gui->current_operation) - { - case CWINDOW_SCROLL: - result = 1; - break; + switch( gui->current_operation ) { + case CWINDOW_SCROLL: + result = 1; + break; - case CWINDOW_RULER: - do_ruler(0, 0, 0, 1); - break; + case CWINDOW_RULER: + do_ruler(0, 0, 0, 1); + break; - case CWINDOW_CAMERA: - mwindow->undo->update_undo_after(_("camera"), LOAD_AUTOMATION); - break; + case CWINDOW_CAMERA: + undo_label = _("camera"); + break; - case CWINDOW_PROJECTOR: - mwindow->undo->update_undo_after(_("projector"), LOAD_AUTOMATION); - break; + case CWINDOW_PROJECTOR: + undo_label = _("projector"); + break; - case CWINDOW_MASK: - case CWINDOW_MASK_CONTROL_IN: - case CWINDOW_MASK_CONTROL_OUT: - case CWINDOW_MASK_TRANSLATE: + case CWINDOW_MASK: + case CWINDOW_MASK_CONTROL_IN: + case CWINDOW_MASK_CONTROL_OUT: + case CWINDOW_MASK_TRANSLATE: // Finish mask operation - gui->mask_keyframe = 0; - mwindow->undo->update_undo_after(_("mask"), LOAD_AUTOMATION); - break; - case CWINDOW_NONE: - result = Canvas::button_release_event(); - break; + gui->mask_keyframe = 0; + undo_label = _("mask"); + break; + case CWINDOW_MASK_ROTATE: + gui->mask_keyframe = 0; + undo_label = _("mask rotate"); + break; + case CWINDOW_MASK_SCALE: + gui->mask_keyframe = 0; + undo_label = _("mask scale"); + break; + case CWINDOW_NONE: + result = Canvas::button_release_event(); + break; } + if( undo_label ) + mwindow->undo->update_undo_after(undo_label, LOAD_AUTOMATION); gui->current_operation = CWINDOW_NONE; return result; } @@ -3458,14 +3363,11 @@ void CWindowCanvas::zoom_resize_window(float percentage) int canvas_w, canvas_h; int new_w, new_h; - // Get required canvas size calculate_sizes(mwindow->edl->get_aspect_ratio(), mwindow->edl->session->output_w, mwindow->edl->session->output_h, - percentage, - canvas_w, - canvas_h); + percentage, canvas_w, canvas_h); // Estimate window size from current borders new_w = canvas_w + (gui->get_w() - mwindow->theme->ccanvas_w); @@ -3498,5 +3400,10 @@ int CWindowCanvas::get_cwindow_controls() return mwindow->session->cwindow_controls; } - +int CWindowCanvas::get_clear_color() +{ + int color = mwindow->edl->session->cwindow_clear_color; + if( color < 0 ) color = Canvas::get_clear_color(); + return color; +}