X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fcwindowgui.C;h=0ee1d6751906ec6a4992c6feaf4c90ade928c9a5;hp=383445ae82ad5f8fedec9b8422e7d6672fbde4b3;hb=f7444a58936e4ab8fa7e7062281567cbc74e175f;hpb=476e13a24aad6d0dc6006cd421e9bd2a89977ea1 diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index 383445ae..0ee1d675 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -119,6 +119,7 @@ CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow) CWindowGUI::~CWindowGUI() { + cwindow->stop_playback(1); if(tool_panel) delete tool_panel; delete meters; delete composite_panel; @@ -419,7 +420,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 +444,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() @@ -672,7 +673,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(); @@ -698,7 +699,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 +711,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) @@ -1125,15 +1126,9 @@ float CWindowCanvas::get_zoom() void CWindowCanvas::draw_refresh(int flush) { - if( get_canvas() && !get_canvas()->get_video_on() ) { + BC_WindowBase *window = get_canvas(); + if( window && !window->get_video_on() ) { clear(0); - if( mwindow->uses_opengl() ) { - get_canvas()->unlock_window(); - mwindow->playback_3d->finish_output(); - get_canvas()->lock_window("CWindowCanvas::draw_refresh"); - get_canvas()->flush(); - get_canvas()->sync_display(); - } 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; @@ -1159,7 +1154,7 @@ 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, + window->draw_vframe(refresh_frame, (int)out_x1, (int)out_y1, (int)(out_x2 - out_x1), (int)(out_y2 - out_y1), @@ -1171,7 +1166,7 @@ void CWindowCanvas::draw_refresh(int flush) } //usleep(10000); draw_overlays(); - get_canvas()->flash(flush); + window->flash(flush); } //printf("CWindowCanvas::draw_refresh 10\n"); } @@ -1185,10 +1180,6 @@ void CWindowCanvas::draw_crophandle(int x, int y) } - - - - #define CONTROL_W 10 #define CONTROL_H 10 #define FIRST_CONTROL_W 20 @@ -1199,8 +1190,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, @@ -1494,11 +1483,17 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, 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 @@ -1506,19 +1501,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. @@ -1526,28 +1518,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); } @@ -1721,15 +1707,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( @@ -1759,23 +1745,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, @@ -1795,9 +1787,23 @@ 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; + 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); } //printf("CWindowCanvas::do_mask 1\n"); } @@ -1826,7 +1832,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); @@ -1996,17 +2013,12 @@ 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(); + ArrayList &mask_points = points; #else SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask); - MaskPoint *point = mask->points.values[gui->affected_point]; + 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; @@ -2014,18 +2026,15 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, gui->control_out_x = point->control_x2; gui->control_out_y = point->control_y2; gui->tool_panel->raise_window(); -#endif } //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 @@ -2036,12 +2045,13 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender, gui->current_operation != CWINDOW_NONE) { // mwindow->undo->update_undo_before(_("mask point"), this); #ifdef USE_KEYFRAME_SPANNING - MaskPoint *point = points.get(gui->affected_point); + ArrayList &mask_points = points; #else - MaskPoint *point = mask->points.get(gui->affected_point); + ArrayList &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; @@ -2049,39 +2059,62 @@ 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; - } -#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; - } -#endif - gui->x_origin = mask_cursor_x; - gui->y_origin = mask_cursor_y; - break; + case CWINDOW_MASK_TRANSLATE: + 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; + break; + case CWINDOW_MASK_ROTATE: + rotate = 1; + case CWINDOW_MASK_SCALE: { + int button_no = get_buttonpress(); + 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; + if( mask_gui && mask_gui->focused ) { + gui->x_origin = atof(mask_gui->focus_x->get_text()); + gui->y_origin = atof(mask_gui->focus_y->get_text()); + } + for( int i=0; ix - 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 + 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; + } + break; } } if( !EQUIV(last_x, point->x) || @@ -2159,6 +2192,20 @@ 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); + int v = mask_gui->focused ? 0 : 1; + get_canvas()->unlock_window(); + mask_gui->lock_window("CWindowCanvas::do_mask_focus"); + mask_gui->set_focused(v, 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; @@ -3269,7 +3316,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; @@ -3300,8 +3347,21 @@ 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 = 1; + 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: @@ -3319,6 +3379,7 @@ int CWindowCanvas::button_press_event() int CWindowCanvas::button_release_event() { int result = 0; + const char *undo_label = 0; switch(gui->current_operation) { @@ -3331,11 +3392,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: @@ -3344,13 +3405,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; }