X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fcwindowgui.C;h=99c395bee41f314ebe9ba94f527f3f0d15d6bcc0;hp=af4d818d8378c257edac3ea08e54aae079ebaaa4;hb=505506bd554eff241bd0a5b5b84c220cb2c59971;hpb=c857b2fb7965d27d86d5785fb9f1b8957a871a1a diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index af4d818d..99c395be 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()) { @@ -129,6 +125,7 @@ CWindowGUI::~CWindowGUI() delete zoom_panel; delete active; delete inactive; + delete focus_frame; delete orig_mask_keyframe; } @@ -139,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); @@ -210,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(); @@ -1001,44 +993,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; } @@ -1129,14 +1089,6 @@ void CWindowCanvas::draw_refresh(int flush) BC_WindowBase *window = get_canvas(); if( window && !window->get_video_on() ) { clear(0); - if( mwindow->uses_opengl() ) { -// this code is to idle rendering before drawing overlays on refresh frame -// if this is not done, occationally opengl finishs late, and overwrites -// the x11 refresh frame and the overlay is not visible. Rarely happens. - unlock_canvas(); - mwindow->playback_3d->finish_output(this); - lock_canvas("CWindowCanvas::draw_refresh"); - } 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; @@ -1486,16 +1438,22 @@ 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); + Auto *prev_auto = 0; + mask_autos->get_prev_auto(position, PLAY_FORWARD, (Auto *&)prev_auto, 1); + MaskAuto *prev_mask = (MaskAuto *)prev_auto; ArrayList points; // Determine the points based on whether @@ -1503,19 +1461,16 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, // 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. @@ -1523,28 +1478,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); } @@ -1718,15 +1667,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( @@ -1756,23 +1705,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, @@ -1792,20 +1747,61 @@ 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; + 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 = @@ -2009,13 +2005,21 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask); ArrayList &mask_points = mask->points; #endif - 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; + 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(); } @@ -2084,17 +2088,38 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, double scale = button_no == WHEEL_UP ? 1.02 : 0.98; double theta = button_no == WHEEL_UP ? M_PI/360. : -M_PI/360.; float st = sin(theta), ct = cos(theta); - gui->x_origin = mask_cursor_x; - gui->y_origin = mask_cursor_y; + float cx = 0, cy = 0; + int n = mask_points.size(); + if( mask_gui && mask_gui->focused ) { + cx = atof(mask_gui->focus_x->get_text()); + cy = atof(mask_gui->focus_y->get_text()); + } + else if( n > 0 ) { + for( int i=0; ix; cy += point->y; + } + cx /= n; cy /= n; + } + gui->x_origin = cx; + gui->y_origin = cy; for( int i=0; ix - mask_cursor_x; - float py = point->y - mask_cursor_y; + float px = point->x - gui->x_origin; + float py = point->y - gui->y_origin; float nx = !rotate ? px*scale : px*ct + py*st; float ny = !rotate ? py*scale : py*ct - px*st; - point->x = nx + mask_cursor_x; - point->y = ny + mask_cursor_y; + 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*scale : px*ct + py*st; + point->control_y1 = !rotate ? py*scale : py*ct - px*st; + px = point->control_x2; py = point->control_y2; + point->control_x2 = !rotate ? px*scale : px*ct + py*st; + point->control_y2 = !rotate ? py*scale : py*ct - px*st; } + rerender = 1; + redraw = 1; break; } } @@ -2173,6 +2198,19 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, 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); + get_canvas()->unlock_window(); + mask_gui->lock_window("CWindowCanvas::do_mask_focus"); + mask_gui->set_focused(1, cx, cy); + mask_gui->unlock_window(); + get_canvas()->lock_window("CWindowCanvas::do_mask_focus"); + return 1; +} + int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw) { int result = 0; @@ -2944,7 +2982,7 @@ int CWindowCanvas::test_bezier(int button_press, // Get target keyframe if( !gui->affected_x && !gui->affected_y && !gui->affected_z ) { - if(!gui->affected_track) return 0; + 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 ) { @@ -3042,8 +3080,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 @@ -3214,12 +3251,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: @@ -3247,12 +3279,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; } } @@ -3283,7 +3311,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; @@ -3318,6 +3346,10 @@ int CWindowCanvas::button_press_event() 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);