mask focus/pivot pt tweaks, set mask_track_id on update_project, ffmpeg cuda open...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / cwindowgui.C
index 3e9bf9ecd8e150fad157a3354ac8f3e90f0d48ec..99c395bee41f314ebe9ba94f527f3f0d15d6bcc0 100644 (file)
@@ -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,7 +1438,7 @@ 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;
@@ -1757,8 +1709,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                if( draw_boundary ) {
                                                        char mask_label[BCSTRLEN];
                                                        int k = mwindow->edl->session->cwindow_mask;
-                                                       if( !prev_mask || prev_mask->is_default ||
-                                                           k < 0 || k >= prev_mask->masks.size() )
+                                                       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);
@@ -1807,23 +1758,50 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                        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; i<n; ++i ) {
+                               MaskPoint *point = points.get(i);
+                               cx += point->x;  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 =
@@ -2027,13 +2005,21 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask);
                ArrayList<MaskPoint*> &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();
        }
 
@@ -2102,12 +2088,21 @@ 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 ) {
-                                       gui->x_origin = atof(mask_gui->focus_x->get_text());
-                                       gui->y_origin = atof(mask_gui->focus_y->get_text());
+                                       cx = atof(mask_gui->focus_x->get_text());
+                                       cy = atof(mask_gui->focus_y->get_text());
+                               }
+                               else if( n > 0 ) {
+                                       for( int i=0; i<n; ++i ) {
+                                               MaskPoint *point = mask_points.values[i];
+                                               cx += point->x;  cy += point->y;
+                                       }
+                                       cx /= n;  cy /= n;
                                }
+                               gui->x_origin = cx;
+                               gui->y_origin = cy;
                                for( int i=0; i<mask_points.size(); ++i ) {
                                        MaskPoint *point = mask_points.values[i];
                                        float px = point->x - gui->x_origin;
@@ -2123,6 +2118,8 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        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; }
                        }
 
@@ -2206,10 +2203,9 @@ 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->set_focused(1, cx, cy);
        mask_gui->unlock_window();
        get_canvas()->lock_window("CWindowCanvas::do_mask_focus");
        return 1;
@@ -2986,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 ) {
@@ -3084,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
@@ -3256,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:
@@ -3289,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;
                }
        }
 
@@ -3362,8 +3348,7 @@ int CWindowCanvas::button_press_event()
                                        break;
                                case MIDDLE_BUTTON: {  // && shift_down()
                                        result = do_mask_focus();
-                                       redraw = 1;
-                                       redraw_canvas = 1;
+                                       redraw = redraw_canvas = 1;
                                        break; }
                                case WHEEL_UP:
                                case WHEEL_DOWN: