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,
+ xS(100), yS(100), 1, 1, 1,
BC_WindowBase::get_resources()->bg_color,
mwindow->get_cwindow_display())
{
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();
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))
#ifdef USE_SLIDER
CWindowSlider::CWindowSlider(MWindow *mwindow, CWindow *cwindow, int x, int y, int pixels)
- : BC_PercentageSlider(x,
- y,
- 0,
- pixels,
- pixels,
- 0,
- 1,
- 0)
+ : BC_PercentageSlider(x, y, 0, pixels, pixels, 0, 1, 0)
{
this->mwindow = mwindow;
this->cwindow = cwindow;
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;
}
CWindowCanvas::CWindowCanvas(MWindow *mwindow, CWindowGUI *gui)
- : Canvas(mwindow,
- gui,
- mwindow->theme->ccanvas_x,
- mwindow->theme->ccanvas_y,
- mwindow->theme->ccanvas_w,
- mwindow->theme->ccanvas_h,
- 0,
- 0,
- mwindow->edl->session->cwindow_scrollbars)
+ : Canvas(mwindow, gui,
+ mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y,
+ mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h,
+ 0, 0, mwindow->edl->session->cwindow_scrollbars)
{
this->mwindow = mwindow;
this->gui = gui;
//printf("CWindowCanvas::draw_refresh 10\n");
}
-#define CROPHANDLE_W 10
-#define CROPHANDLE_H 10
+#define CROPHANDLE_W xS(10)
+#define CROPHANDLE_H yS(10)
void CWindowCanvas::draw_crophandle(int x, int y)
{
}
-#define CONTROL_W 10
-#define CONTROL_H 10
-#define FIRST_CONTROL_W 20
-#define FIRST_CONTROL_H 20
+#define CONTROL_W xS(10)
+#define CONTROL_H yS(10)
+#define FIRST_CONTROL_W xS(20)
+#define FIRST_CONTROL_H yS(20)
#undef BC_INFINITY
#define BC_INFINITY 65536
-#define RULERHANDLE_W 16
-#define RULERHANDLE_H 16
+#define RULERHANDLE_W xS(16)
+#define RULERHANDLE_H yS(16)
-int CWindowCanvas::do_ruler(int draw,
- int motion,
- int button_press,
- int button_release)
+int CWindowCanvas::do_ruler(int draw, int motion,
+ int button_press, int button_release)
{
int result = 0;
float x1 = mwindow->edl->session->ruler_x1;
{
double angle_value = fabs(atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) /
(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) *
- 360 /
- 2 /
- M_PI);
+ 360 / 2 / M_PI);
double distance_value =
sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) +
SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1));
{
double angle_value = fabs(atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) /
(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) *
- 360 /
- 2 /
- M_PI);
+ 360 / 2 / M_PI);
double distance_value =
sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) +
SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1));
{
// 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;
Auto *prev_auto = 0;
mask_autos->get_prev_auto(position, PLAY_FORWARD, (Auto *&)prev_auto, 1);
MaskAuto *prev_mask = (MaskAuto *)prev_auto;
- ArrayList<MaskPoint*> points;
-
+ 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( draw && mask_gui && mask_gui->focused ) {
float fx = atof(mask_gui->focus_x->get_text());
float fy = atof(mask_gui->focus_y->get_text());
+ fx = (fx - half_track_w) * projector_z + projector_x;
+ fy = (fy - half_track_h) * projector_z + projector_y;
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_color(WHITE);
#endif
}
- if( draw && mask_gui && mask_gui->center_mark && points.size() ) {
+ if( draw && mask_gui && draw_markers && points.size() ) {
float cx = 0, cy = 0;
int n = points.size();
for( int i=0; i<n; ++i ) {
cx += point->x; cy += point->y;
}
cx /= n; cy /= n;
+ if( !mask_gui->focused )
+ mask_gui->set_focused(0, cx, cy);
+ cx = (cx - half_track_w) * projector_z + projector_x;
+ cy = (cy - half_track_h) * projector_z + projector_y;
output_to_canvas(mwindow->edl, 0, cx, cy);
float r = bmax(cvs_win->get_w(), cvs_win->get_h());
- float d = 0.003*r;
+ 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);
}
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 =
(MaskAuto*)gui->cwindow->calculate_affected_auto(
- mask_autos,
- 0);
+ mask_autos, 0);
gui->orig_mask_keyframe->copy_data(gui->mask_keyframe);
#else
gui->mask_keyframe =
(MaskAuto*)gui->cwindow->calculate_affected_auto(
- mask_autos,
- 1);
+ mask_autos, 1);
#endif
}
SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask);
if(button_press && result) {
#ifdef USE_KEYFRAME_SPANNING
- ArrayList<MaskPoint*> &mask_points = points;
+ MaskPoints &mask_points = points;
#else
SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask);
- ArrayList<MaskPoint*> &mask_points = mask->points;
+ MaskPoints &mask_points = mask->points;
#endif
int k = gui->affected_point;
if( k >= 0 && k < mask_points.size() ) {
//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;
+ MaskPoints &mask_points = points;
#else
- ArrayList<MaskPoint*> &mask_points = mask->points;
+ MaskPoints &mask_points = mask->points;
#endif
MaskPoint *point = mask_points.get(gui->affected_point);
// canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
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;
+ 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; j<n; ++j ) {
+ if( !mask_gui->mask_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; i<points.size(); ++i ) {
+ MaskPoint *point = points[i];
+ if( mode == MASK_SCALE_X || mode == MASK_SCALE_XY ) point->x += dx;
+ if( mode == MASK_SCALE_Y || mode == MASK_SCALE_XY ) point->y += dy;
+ }
}
gui->x_origin = mask_cursor_x;
gui->y_origin = mask_cursor_y;
- break;
+ 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; i<n; ++i ) {
+ MaskPoint *point = mask_points.values[i];
+ cx += point->x; cy += point->y;
+ }
+ 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 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;
+ int mode = mask_gui->scale_mode;
+ double xscale = !rotate && (mode == MASK_SCALE_X ||
+ mode == MASK_SCALE_XY ) ? scale : 1.;
+ double yscale = !rotate && (mode == MASK_SCALE_Y ||
+ mode == MASK_SCALE_XY ) ? scale : 1.;
+ double theta = button_no == WHEEL_UP ? dt : -dt;
+ if( rotate ? theta==0 : scale==1 ) break;
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; 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 ) {
+ if( !mask_gui->mask_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; 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*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;
}
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; k<SUBMASKS; ++k ) {
+ if( k == mwindow->edl->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; i<edge.size(); ++i ) {
+ MaskCoord a = edge[i];
+ MaskCoord b = i<edge.size()-1 ? edge[i+1] : edge[0];
+ float ax = a.x, ay = a.y;
+ float bx = b.x, by = b.y;
+ output_to_canvas(mwindow->edl, 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;
+ Track *track = gui->cwindow->calculate_affected_track();
+ int64_t position = track->to_units(
+ mwindow->edl->local_session->get_selectionstart(1),
+ 0);
+ float projector_x, projector_y, projector_z;
+ track->automation->get_projector(
+ &projector_x, &projector_y, &projector_z,
+ position, PLAY_FORWARD);
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");
+ projector_x += mwindow->edl->session->output_w / 2;
+ projector_y += mwindow->edl->session->output_h / 2;
+ float half_track_w = (float)track->track_w / 2;
+ float half_track_h = (float)track->track_h / 2;
+ cx = (cx - projector_x) / projector_z + half_track_w;
+ cy = (cy - projector_y) / projector_z + half_track_h;
+ CWindowMaskGUI *mask_gui = (CWindowMaskGUI*) gui->tool_panel->tool_gui;
+ mask_gui->set_focused(1, cx, cy);
return 1;
}
// 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 ) {
float z_val = gui->affected_z->get_value();
if( gui->translating_zoom ) {
- float z = gui->center_z + (cursor_y - gui->y_origin) / 128;
+ float z = gui->center_z + (cursor_y - gui->y_origin) / yS(128);
if( z < 0 ) z = 0;
if( !EQUIV(z_val, z) ) {
rerender = 1;
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
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:
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;
}
}
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:
return mwindow->session->cwindow_controls;
}
-
+int CWindowCanvas::get_clear_color()
+{
+ int color = mwindow->edl->session->cwindow_clear_color;
+ if( color < 0 ) color = get_canvas()->get_bg_color();
+ return color;
+}