CWindowGUI::~CWindowGUI()
{
+ cwindow->stop_playback(1);
if(tool_panel) delete tool_panel;
delete meters;
delete composite_panel;
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)
edit_panel->update();
tool_panel->start_tool(value);
- canvas->draw_refresh();
+ canvas->refresh(0);
}
void CWindowGUI::update_tool()
{
if( redraw ) {
update_tool();
- canvas->draw_refresh();
+ canvas->refresh(1);
}
if( change_type < 0 && !overlay ) return;
unlock_window();
mwindow->sync_parameters(change_type);
}
if( overlay ) {
- mwindow->gui->lock_window("CWindow::camera_keyframe");
+ mwindow->gui->lock_window("CWindowGUI::sync_parameters");
mwindow->gui->draw_overlays(1);
mwindow->gui->unlock_window();
}
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()
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)
void CWindowCanvas::draw_refresh(int flush)
{
- if(get_canvas() && !get_canvas()->get_video_on())
- {
-
- if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0)
- {
+ 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;
get_transfers(mwindow->edl,
- in_x1,
- in_y1,
- in_x2,
- in_y2,
- out_x1,
- out_y1,
- out_x2,
- out_y2);
-
- if(!EQUIV(out_x1, 0) ||
- !EQUIV(out_y1, 0) ||
- !EQUIV(out_x2, get_canvas()->get_w()) ||
- !EQUIV(out_y2, get_canvas()->get_h()))
- {
- get_canvas()->clear_box(0,
- 0,
- get_canvas()->get_w(),
- get_canvas()->get_h());
- }
+ in_x1, in_y1, in_x2, in_y2,
+ out_x1, out_y1, out_x2, out_y2);
+
//printf("CWindowCanvas::draw_refresh %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",
//in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2);
- if(out_x2 > out_x1 &&
- out_y2 > out_y1 &&
- in_x2 > in_x1 &&
- in_y2 > in_y1)
- {
+ if( out_x2 > out_x1 && out_y2 > out_y1 &&
+ in_x2 > in_x1 && in_y2 > in_y1 ) {
// input scaled from session to refresh frame coordinates
int ow = get_output_w(mwindow->edl);
int oh = get_output_h(mwindow->edl);
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,
- (int)out_x1,
- (int)out_y1,
+ window->draw_vframe(refresh_frame,
+ (int)out_x1, (int)out_y1,
(int)(out_x2 - out_x1),
(int)(out_y2 - out_y1),
- (int)in_x1,
- (int)in_y1,
+ (int)in_x1, (int)in_y1,
(int)(in_x2 - in_x1),
(int)(in_y2 - in_y1),
0);
}
}
- else
- {
- get_canvas()->clear_box(0,
- 0,
- get_canvas()->get_w(),
- get_canvas()->get_h());
- }
-
+//usleep(10000);
draw_overlays();
-// allow last opengl write to complete before redraw
-// tried sync_display, glFlush, glxMake*Current(0..)
-usleep(20000);
- get_canvas()->flash(flush);
+ window->flash(flush);
}
//printf("CWindowCanvas::draw_refresh 10\n");
}
}
-
-
-
-
#define CONTROL_W 10
#define CONTROL_H 10
#define FIRST_CONTROL_W 20
#define RULERHANDLE_W 16
#define RULERHANDLE_H 16
-
-
int CWindowCanvas::do_ruler(int draw,
int motion,
int button_press,
}
//printf("CWindowCanvas::do_mask 1\n");
+ BC_WindowBase *cvs_win = get_canvas();
if(draw) {
- get_canvas()->draw_polygon(&x_points, &y_points);
- get_canvas()->set_opaque();
+ cvs_win->draw_polygon(&x_points, &y_points);
+ cvs_win->set_opaque();
+ }
+ if( draw && gui->tool_panel ) {
+ CWindowMaskGUI *mask_gui = (CWindowMaskGUI*)gui->tool_panel->tool_gui;
+ if( 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");
}
}
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);
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<MaskPoint*> &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<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_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
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<MaskPoint*> &mask_points = points;
#else
- MaskPoint *point = mask->points.get(gui->affected_point);
+ ArrayList<MaskPoint*> &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;
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;
+ 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( gui->tool_panel ) {
+ CWindowMaskGUI *mask_gui = (CWindowMaskGUI*)gui->tool_panel->tool_gui;
+ 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());
}
-#endif
- gui->x_origin = mask_cursor_x;
- gui->y_origin = mask_cursor_y;
- break;
+ }
+ 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;
+ }
+ break; }
}
if( !EQUIV(last_x, point->x) ||
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;
switch(mwindow->edl->session->cwindow_operation)
{
case CWINDOW_CAMERA:
- draw_bezier(1);
+ draw_outlines(1);
break;
case CWINDOW_PROJECTOR:
- draw_bezier(0);
+ draw_outlines(0);
break;
case CWINDOW_CROP:
}
-
-
-
-
-
-
-void CWindowCanvas::draw_bezier(int do_camera)
+void CWindowCanvas::draw_outlines(int do_camera)
{
Track *track = gui->cwindow->calculate_affected_track();
if(!track) return;
- float center_x;
- float center_y;
- float center_z;
+ float proj_x, proj_y, proj_z;
int64_t position = track->to_units(
mwindow->edl->local_session->get_selectionstart(1),
0);
- if( do_camera ) {
- track->automation->get_camera(¢er_x,
- ¢er_y, ¢er_z, position, PLAY_FORWARD);
-// follow image, not camera
- center_x = -center_x * center_z; center_y = -center_y * center_z;
- }
- else
- track->automation->get_projector(¢er_x,
- ¢er_y, ¢er_z, position, PLAY_FORWARD);
-
-// center_x += track->track_w / 2;
-// center_y += track->track_h / 2;
- center_x += mwindow->edl->session->output_w / 2;
- center_y += mwindow->edl->session->output_h / 2;
- float track_x1 = center_x - track->track_w / 2 * center_z;
- float track_y1 = center_y - track->track_h / 2 * center_z;
- float track_x2 = track_x1 + track->track_w * center_z;
- float track_y2 = track_y1 + track->track_h * center_z;
-
- output_to_canvas(mwindow->edl, 0, track_x1, track_y1);
- output_to_canvas(mwindow->edl, 0, track_x2, track_y2);
+ track->automation->get_projector(&proj_x, &proj_y, &proj_z,
+ position, PLAY_FORWARD);
+
+ proj_x += mwindow->edl->session->output_w/2.;
+ proj_y += mwindow->edl->session->output_h/2.;
+ float proj_x1 = proj_x - track->track_w/2. * proj_z;
+ float proj_y1 = proj_y - track->track_h/2. * proj_z;
+ float proj_x2 = proj_x + track->track_w/2. * proj_z;
+ float proj_y2 = proj_y + track->track_h/2. * proj_z;
+ float x1 = proj_x1, x2 = proj_x2;
+ float y1 = proj_y1, y2 = proj_y2;
+ output_to_canvas(mwindow->edl, 0, x1, y1);
+ output_to_canvas(mwindow->edl, 0, x2, y2);
#define DRAW_PROJECTION(offset) \
- get_canvas()->draw_rectangle((int)track_x1 + offset, \
- (int)track_y1 + offset, \
- (int)(track_x2 - track_x1), \
- (int)(track_y2 - track_y1)); \
- get_canvas()->draw_line((int)track_x1 + offset, \
- (int)track_y1 + offset, \
- (int)track_x2 + offset, \
- (int)track_y2 + offset); \
- get_canvas()->draw_line((int)track_x2 + offset, \
- (int)track_y1 + offset, \
- (int)track_x1 + offset, \
- (int)track_y2 + offset); \
-
+ get_canvas()->draw_rectangle(x1+offset, y1+offset, (x2-x1), (y2-y1)); \
+ get_canvas()->draw_line(x1+offset, y1+offset, x2+offset, y2+offset); \
+ get_canvas()->draw_line(x2+offset, y1+offset, x1+offset, y2+offset); \
// Drop shadow
get_canvas()->set_color(BLACK);
DRAW_PROJECTION(1);
-
-// canvas->set_inverse();
- if(do_camera)
- get_canvas()->set_color(GREEN);
- else
- get_canvas()->set_color(RED);
-
+ get_canvas()->set_color(do_camera ? GREEN : RED);
DRAW_PROJECTION(0);
-// canvas->set_opaque();
+ if( do_camera ) {
+ float cam_x, cam_y, cam_z;
+ track->automation->get_camera(&cam_x, &cam_y, &cam_z,
+ position, PLAY_FORWARD);
+ cam_x += track->track_w / 2.;
+ cam_y += track->track_h / 2.;
+// follow image, not camera
+ cam_x = -cam_x; cam_y = -cam_y; cam_z *= proj_z;
+ float cam_x1 = cam_x * cam_z + proj_x;
+ float cam_y1 = cam_y * cam_z + proj_y;
+ float cam_x2 = (cam_x + track->track_w) * cam_z + proj_x;
+ float cam_y2 = (cam_y + track->track_h) * cam_z + proj_y;
+ output_to_canvas(mwindow->edl, 0, cam_x1, cam_y1);
+ output_to_canvas(mwindow->edl, 0, cam_x2, cam_y2);
+ get_canvas()->set_color(YELLOW);
+ get_canvas()->draw_rectangle(cam_x1, cam_y1, cam_x2-cam_x1, cam_y2-cam_y1);
+ }
}
int CWindowCanvas::test_bezier(int button_press,
// 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;
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:
int CWindowCanvas::button_release_event()
{
int result = 0;
+ const char *undo_label = 0;
switch(gui->current_operation)
{
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:
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;
}