X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fcwindowgui.C;h=935a5f9fc9798ee6611e5348945dba722a9bd27a;hp=02ed52d32ad93ae559acb39554362dd0ce85e5d1;hb=6d8835a537ca709e122226506548de0d4942aa32;hpb=b4184445f396e16260ed90e645a280149aeda8c0 diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index 02ed52d3..935a5f9f 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -78,14 +78,10 @@ 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_y, + mwindow->session->cwindow_w, + mwindow->session->cwindow_h, + 100, 100, 1, 1, 1, BC_WindowBase::get_resources()->bg_color, mwindow->get_cwindow_display()) { @@ -119,6 +115,7 @@ CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow) CWindowGUI::~CWindowGUI() { + cwindow->stop_playback(1); if(tool_panel) delete tool_panel; delete meters; delete composite_panel; @@ -128,6 +125,7 @@ CWindowGUI::~CWindowGUI() 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); @@ -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(); @@ -419,7 +412,7 @@ void CWindowGUI::zoom_canvas(double value, int update_menu) canvas->reposition_window(mwindow->edl, mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y, mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h); - canvas->draw_refresh(); + canvas->refresh(0); } void CWindowGUI::set_operation(int value) @@ -443,7 +436,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() @@ -480,7 +473,7 @@ int CWindowGUI::keypress_event() break; case 'f': unlock_window(); - if(mwindow->session->cwindow_fullscreen) + if( canvas->get_fullscreen() ) canvas->stop_fullscreen(); else canvas->start_fullscreen(); @@ -506,7 +499,7 @@ int CWindowGUI::keypress_event() break; case ESC: unlock_window(); - if(mwindow->session->cwindow_fullscreen) + if( canvas->get_fullscreen() ) canvas->stop_fullscreen(); lock_window("CWindowGUI::keypress_event 4"); result = 1; @@ -672,7 +665,7 @@ void CWindowGUI::sync_parameters(int change_type, int redraw, int overlay) { if( redraw ) { update_tool(); - canvas->draw_refresh(); + canvas->refresh(1); } if( change_type < 0 && !overlay ) return; unlock_window(); @@ -681,7 +674,7 @@ void CWindowGUI::sync_parameters(int change_type, int redraw, int overlay) 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(); } @@ -698,7 +691,7 @@ void CWindowGUI::drag_motion() 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() @@ -710,7 +703,7 @@ int CWindowGUI::drag_stop() 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) @@ -885,6 +878,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)) @@ -1000,44 +994,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; } @@ -1093,17 +1055,6 @@ 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; @@ -1136,43 +1087,23 @@ float CWindowCanvas::get_zoom() void CWindowCanvas::draw_refresh(int flush) { - if(get_canvas() && !get_canvas()->get_video_on()) - { - - if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0) - { + 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); @@ -1184,31 +1115,19 @@ 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"); } @@ -1222,10 +1141,6 @@ void CWindowCanvas::draw_crophandle(int x, int y) } - - - - #define CONTROL_W 10 #define CONTROL_H 10 #define FIRST_CONTROL_W 20 @@ -1236,8 +1151,6 @@ void CWindowCanvas::draw_crophandle(int x, int y) #define RULERHANDLE_W 16 #define RULERHANDLE_H 16 - - int CWindowCanvas::do_ruler(int draw, int motion, int button_press, @@ -1526,36 +1439,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; //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. @@ -1563,28 +1479,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); } @@ -1758,15 +1668,15 @@ 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( j == segments ) { + if( draw && draw_markers ) { // Draw second anchor if(i < points.size() - 1) { if(i == gui->affected_point - 1) get_canvas()->draw_disc( @@ -1796,23 +1706,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, @@ -1832,20 +1748,63 @@ 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()); + 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); + 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(); + 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 = @@ -1863,7 +1822,18 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, } 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()) { mwindow->undo->update_undo_before(_("mask translate"), 0); @@ -2033,52 +2003,54 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, 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; @@ -2086,47 +2058,123 @@ 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: + 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 == 1 || mode == 2) 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 == 0 || mode == 2 ) ? scale : 1.; + double yscale = !rotate && (mode == 1 || mode == 2 ) ? 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; } @@ -2185,17 +2233,51 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, 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() +{ + CWindowMaskGUI *mask_gui = (CWindowMaskGUI*) gui->tool_panel->tool_gui; + float cx = get_cursor_x(), cy = get_cursor_y(); + canvas_to_output(mwindow->edl, 0, cx, cy); + mask_gui->set_focused(1, cx, cy); + return 1; +} + int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) { int result = 0; @@ -2469,11 +2551,11 @@ void CWindowCanvas::draw_overlays() 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: @@ -2884,74 +2966,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; - 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, @@ -2964,114 +3030,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(); } @@ -3080,41 +3103,36 @@ int CWindowCanvas::test_bezier(int button_press, redraw = 1; } - if(gui->translating_zoom) - { - last_center_z = gui->affected_z->get_value(); + 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) / 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); } } @@ -3129,8 +3147,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 @@ -3301,12 +3318,7 @@ int CWindowCanvas::cursor_motion_event() case CWINDOW_MASK_CONTROL_IN: case CWINDOW_MASK_CONTROL_OUT: case CWINDOW_MASK_TRANSLATE: - - result = do_mask(redraw, - rerender, - 0, - 1, - 0); + result = do_mask(redraw, rerender, 0, 1, 0); break; case CWINDOW_EYEDROP: @@ -3334,12 +3346,8 @@ int CWindowCanvas::cursor_motion_event() result = do_ruler(0, 1, 0, 0); break; case CWINDOW_MASK: - result = do_mask(redraw, - rerender, - 0, - 1, - 0); - break; + result = do_mask(redraw, rerender, 0, 1, 0); + break; } } @@ -3370,7 +3378,7 @@ int CWindowCanvas::button_press_event() // 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; @@ -3401,8 +3409,20 @@ int CWindowCanvas::button_press_event() break; case CWINDOW_MASK: - if(get_buttonpress() == 1) + switch( get_buttonpress() ) { + case LEFT_BUTTON: result = do_mask(redraw, rerender, 1, 0, 0); + break; + 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: @@ -3420,6 +3440,7 @@ int CWindowCanvas::button_press_event() int CWindowCanvas::button_release_event() { int result = 0; + const char *undo_label = 0; switch(gui->current_operation) { @@ -3432,11 +3453,11 @@ int CWindowCanvas::button_release_event() break; case CWINDOW_CAMERA: - mwindow->undo->update_undo_after(_("camera"), LOAD_AUTOMATION); + undo_label = _("camera"); break; case CWINDOW_PROJECTOR: - mwindow->undo->update_undo_after(_("projector"), LOAD_AUTOMATION); + undo_label = _("projector"); break; case CWINDOW_MASK: @@ -3445,13 +3466,23 @@ int CWindowCanvas::button_release_event() case CWINDOW_MASK_TRANSLATE: // Finish mask operation gui->mask_keyframe = 0; - mwindow->undo->update_undo_after(_("mask"), LOAD_AUTOMATION); + 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; }