mask mods- accel rotate/scale, gang rotate/scale/xlate, high-lite active mask tracks...
authorGood Guy <[email protected]>
Sat, 29 Jun 2019 19:45:22 +0000 (13:45 -0600)
committerGood Guy <[email protected]>
Sat, 29 Jun 2019 19:45:22 +0000 (13:45 -0600)
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/cwindowtool.C
cinelerra-5.1/cinelerra/cwindowtool.h
cinelerra-5.1/cinelerra/cwindowtool.inc
cinelerra-5.1/guicast/bcwindowbase.C

index 2cfb5da53ffaa2f22a0ccee17721180b2733820e..eaf4af4eddc1d0c3144d1d9dbf4f7001426cb7b5 100644 (file)
@@ -2038,8 +2038,9 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 //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
                        ArrayList<MaskPoint*> &mask_points = points;
@@ -2075,14 +2076,31 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                point->control_y2 = mask_cursor_y - gui->y_origin + gui->control_out_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;
+                       case CWINDOW_MASK_TRANSLATE: {
+                               if( !mask_gui ) break;
+                               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; j<n; ++j ) {
+                                       SubMask *sub_mask = keyframe->get_submask(j);
+                                       if( !sub_mask ) continue;
+                                       ArrayList<MaskPoint*> &points = sub_mask->points;
+                                       for( int i=0; i<points.size(); ++i ) {
+                                               MaskPoint *point = points[i];
+                                               point->x += dx;
+                                               point->y += dy;
+                                       }
                                }
                                gui->x_origin = mask_cursor_x;
                                gui->y_origin = mask_cursor_y;
-                               break;
+                               rerender = 1;
+                               redraw = 1;
+                               track = 0;
+                               break; }
                        case CWINDOW_MASK_ROTATE:
                                rotate = 1;
                        case CWINDOW_MASK_SCALE: {
@@ -2092,7 +2110,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        cx = atof(mask_gui->focus_x->get_text());
                                        cy = atof(mask_gui->focus_y->get_text());
                                }
-                               else if( !gui->alt_down() ) {
+                               else if( !gui->ctrl_down() ) {
                                        cx = cy = 0;
                                        int n = mask_points.size();
                                        for( int i=0; i<n; ++i ) {
@@ -2104,36 +2122,52 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                }
                                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 scale = button_no == WHEEL_UP ? 1.02 : 0.98;
-                               double theta = button_no == WHEEL_UP ? M_PI/360. : -M_PI/360.;
+                               double ds = accel/64., dt = accel*M_PI/360.;
+                               double scale = button_no == WHEEL_UP ? 1.+ds : 1.-ds;
+                               double theta = button_no == WHEEL_UP ? dt : -dt;
+                               if( rotate ? theta==0 : scale==1 ) break;
                                float st = sin(theta), ct = cos(theta);
-                               for( int i=0; i<mask_points.size(); ++i ) {
-                                       MaskPoint *point = mask_points.values[i];
-                                       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 + 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;
+                               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; j<n; ++j ) {
+                                       SubMask *sub_mask = keyframe->get_submask(j);
+                                       ArrayList<MaskPoint*> &points = sub_mask->points;
+                                       if( !sub_mask ) continue;
+                                       for( int i=0; i<points.size(); ++i ) {
+                                               MaskPoint *point = points[i];
+                                               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 + 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;
+                               track = 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;
                        }
index 8470f35487533b10bf5ee694a090a00d1b855068..10aab69c21591c23dde5eee3eba2e9f5568941f2 100644 (file)
@@ -1525,9 +1525,14 @@ int CWindowMaskOnTrack::handle_event()
 void CWindowMaskOnTrack::update_items()
 {
        track_items.remove_all_objects();
+       int high_color = gui->get_resources()->button_highlighted;
        for( Track *track=mwindow->edl->tracks->first; track; track=track->next ) {
                if( track->data_type != TRACK_VIDEO ) continue;
-               int color = track->record ? -1 : RED;
+               MaskAutos *mask_autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
+               int color = !track->record ? RED : mask_autos->first ?  high_color : -1;
+               MaskAuto *mask_auto = (MaskAuto*)mask_autos->default_auto;
+               for( int i=0; color<0 && i<mask_auto->masks.size(); ++i )
+                       if( mask_auto->masks[i]->points.size() > 0 ) color = high_color;
                track_items.append(new CWindowMaskItem(track->title, track->get_id(), color));
        }
        update_list(&track_items);
@@ -2293,6 +2298,24 @@ int CWindowMaskGangFader::handle_event()
        return 1;
 }
 
+CWindowMaskGangFocus::CWindowMaskGangFocus(MWindow *mwindow,
+               CWindowMaskGUI *gui, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("gangpatch_data"), 0)
+{
+        this->mwindow = mwindow;
+        this->gui = gui;
+        set_tooltip(_("Gang rotate/scale/translate"));
+}
+
+CWindowMaskGangFocus::~CWindowMaskGangFocus()
+{
+}
+
+int CWindowMaskGangFocus::handle_event()
+{
+       return 1;
+}
+
 CWindowMaskBeforePlugins::CWindowMaskBeforePlugins(CWindowMaskGUI *gui, int x, int y)
  : BC_CheckBox(x,
        y,
@@ -2550,6 +2573,7 @@ void CWindowMaskGUI::create_objects()
        focus_x = new CWindowCoord(this, x1, y, cx);
        focus_x->create_objects();
        add_subwindow(focus = new CWindowMaskFocus(mwindow, this, del_x, y));
+       add_subwindow(gang_focus = new CWindowMaskGangFocus(mwindow, this, clr_x, y));
        y += focus_x->get_h() + margin;
        add_subwindow(title = new BC_Title(x, y, "Y:"));
        float cy = mwindow->edl->session->output_h / 2.f;
@@ -2567,16 +2591,16 @@ void CWindowMaskGUI::create_objects()
        help_y = y;
        add_subwindow(new BC_Bar(x, y, get_w()-2*x));
        y += bar->get_h() + 2*margin;
-       add_subwindow(new BC_Title(x, y, _(
+       add_subwindow(title = new BC_Title(x, y, _(
                "Shift+LMB: move an end point\n"
                "Ctrl+LMB: move a control point\n"
                "Alt+LMB: to drag translate the mask\n"
                "Shift+Key Delete to delete the point\n"
-               "Wheel Up/Dn: rotate around focal point\n"
-               "Shift+Wheel Up/Dn: scale around focal point\n"
-               "Alt/Shift+Wheel: rotate/scale around pointer\n"
-               "Shift+MMB: Toggle focus center at pointer")));
-       help_h = get_h();
+               "Shift+MMB: Set Pivot Point at pointer\n"
+               "Wheel: rotate around Pivot Point\n"
+               "Shift+Wheel: scale around Pivot Point\n"
+               "Ctrl Wheel: rotate/scale around pointer")));
+       help_h = y + title->get_h() + 2*margin;
        update();
        resize_window(get_w(), help_y);
        unlock_window();
index ced331bc376897462a9dbd324f753f7606f64125..951d30e4d36c6c5c61ca2ebe430a92323f8b3c57 100644 (file)
@@ -312,6 +312,17 @@ public:
        CWindowMaskGUI *gui;
 };
 
+class CWindowMaskGangFocus : public BC_Toggle
+{
+public:
+       CWindowMaskGangFocus(MWindow *mwindow, CWindowMaskGUI *gui,
+                       int x, int y);
+       ~CWindowMaskGangFocus();
+       int handle_event();
+       MWindow *mwindow;
+       CWindowMaskGUI *gui;
+};
+
 class CWindowMaskAffectedPoint : public BC_TumbleTextBox
 {
 public:
@@ -470,6 +481,7 @@ public:
        CWindowCoord *x, *y;
        CWindowMaskFocus *focus;
        int focused;
+       CWindowMaskGangFocus *gang_focus;
        CWindowMaskHelp *help;
        int helped, help_y, help_h;
        CWindowMaskDrawMarkers *draw_markers;
index 35bcf4e9247ad8828687274595172ea25047522d..444460e67098104dbae8e7a945536ffb164e90a7 100644 (file)
@@ -42,6 +42,7 @@ class CWindowMaskEnable;
 class CWindowMaskFade;
 class CWindowMaskFadeSlider;
 class CWindowMaskGangFader;
+class CWindowMaskGangFocus;
 class CWindowMaskAffectedPoint;
 class CWindowMaskFocus;
 class CWindowMaskDrawMarkers;
index 21d6bd37996741580e34057762c763d6066b3010..1ff149285aa2d2c297cf48b2ead4c708d8b23852 100644 (file)
@@ -4060,6 +4060,11 @@ int BC_WindowBase::resize_window(int w, int h)
                size_hints.max_width = w;
                size_hints.min_height = h;
                size_hints.max_height = h;
+               if( this->x > -BC_INFINITY && this->x < BC_INFINITY ) {
+                       size_hints.flags |= PPosition;
+                       size_hints.x = this->x;
+                       size_hints.y = this->y;
+               }
                XSetNormalHints(top_level->display, win, &size_hints);
        }
        XResizeWindow(top_level->display, win, w, h);