00001 #include "automation.h"
00002 #include "autos.h"
00003 #include "bcsignals.h"
00004 #include "canvas.h"
00005 #include "clip.h"
00006 #include "cpanel.h"
00007 #include "cplayback.h"
00008 #include "ctimebar.h"
00009 #include "cursors.h"
00010 #include "cwindowgui.h"
00011 #include "cwindow.h"
00012 #include "cwindowtool.h"
00013 #include "editpanel.h"
00014 #include "edl.h"
00015 #include "edlsession.h"
00016 #include "floatauto.h"
00017 #include "floatautos.h"
00018 #include "keys.h"
00019 #include "language.h"
00020 #include "localsession.h"
00021 #include "mainclock.h"
00022 #include "mainmenu.h"
00023 #include "mainundo.h"
00024 #include "mainsession.h"
00025 #include "maskauto.h"
00026 #include "maskautos.h"
00027 #include "mbuttons.h"
00028 #include "meterpanel.h"
00029 #include "mwindowgui.h"
00030 #include "mwindow.h"
00031 #include "mwindow.h"
00032 #include "playback3d.h"
00033 #include "playtransport.h"
00034 #include "theme.h"
00035 #include "trackcanvas.h"
00036 #include "tracks.h"
00037 #include "transportque.h"
00038 #include "vtrack.h"
00039
00040
00041 static double my_zoom_table[] =
00042 {
00043 0.25,
00044 0.33,
00045 0.50,
00046 0.75,
00047 1.0,
00048 1.5,
00049 2.0,
00050 3.0,
00051 4.0
00052 };
00053
00054 static int total_zooms = sizeof(my_zoom_table) / sizeof(double);
00055
00056
00057 CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow)
00058 : BC_Window(PROGRAM_NAME ": Compositor",
00059 mwindow->session->cwindow_x,
00060 mwindow->session->cwindow_y,
00061 mwindow->session->cwindow_w,
00062 mwindow->session->cwindow_h,
00063 100,
00064 100,
00065 1,
00066 1,
00067 1,
00068 BC_WindowBase::get_resources()->bg_color,
00069 mwindow->edl->session->get_cwindow_display())
00070 {
00071 this->mwindow = mwindow;
00072 this->cwindow = cwindow;
00073 affected_track = 0;
00074 affected_x = 0;
00075 affected_y = 0;
00076 affected_z = 0;
00077 affected_keyframe = 0;
00078 affected_point = 0;
00079 x_offset = 0;
00080 y_offset = 0;
00081 x_origin = 0;
00082 y_origin = 0;
00083 current_operation = CWINDOW_NONE;
00084 tool_panel = 0;
00085 translating_zoom = 0;
00086 active = 0;
00087 inactive = 0;
00088 crop_translate = 0;
00089 }
00090
00091 CWindowGUI::~CWindowGUI()
00092 {
00093 if(tool_panel) delete tool_panel;
00094 delete meters;
00095 delete composite_panel;
00096 delete canvas;
00097 delete transport;
00098 delete edit_panel;
00099 delete zoom_panel;
00100 delete active;
00101 delete inactive;
00102 }
00103
00104 int CWindowGUI::create_objects()
00105 {
00106 set_icon(mwindow->theme->get_image("cwindow_icon"));
00107
00108 active = new BC_Pixmap(this, mwindow->theme->get_image("cwindow_active"));
00109 inactive = new BC_Pixmap(this, mwindow->theme->get_image("cwindow_inactive"));
00110
00111 mwindow->theme->get_cwindow_sizes(this, mwindow->session->cwindow_controls);
00112 mwindow->theme->draw_cwindow_bg(this);
00113 flash();
00114
00115
00116 meters = new CWindowMeters(mwindow,
00117 this,
00118 mwindow->theme->cmeter_x,
00119 mwindow->theme->cmeter_y,
00120 mwindow->theme->cmeter_h);
00121 meters->create_objects();
00122
00123
00124 composite_panel = new CPanel(mwindow,
00125 this,
00126 mwindow->theme->ccomposite_x,
00127 mwindow->theme->ccomposite_y,
00128 mwindow->theme->ccomposite_w,
00129 mwindow->theme->ccomposite_h);
00130 composite_panel->create_objects();
00131
00132 canvas = new CWindowCanvas(mwindow, this);
00133 canvas->create_objects(mwindow->edl);
00134
00135
00136 add_subwindow(timebar = new CTimeBar(mwindow,
00137 this,
00138 mwindow->theme->ctimebar_x,
00139 mwindow->theme->ctimebar_y,
00140 mwindow->theme->ctimebar_w,
00141 mwindow->theme->ctimebar_h));
00142 timebar->create_objects();
00143
00144 add_subwindow(slider = new CWindowSlider(mwindow,
00145 cwindow,
00146 mwindow->theme->cslider_x,
00147 mwindow->theme->cslider_y,
00148 mwindow->theme->cslider_w));
00149
00150 transport = new CWindowTransport(mwindow,
00151 this,
00152 mwindow->theme->ctransport_x,
00153 mwindow->theme->ctransport_y);
00154 transport->create_objects();
00155 transport->set_slider(slider);
00156
00157 edit_panel = new CWindowEditing(mwindow, cwindow);
00158 edit_panel->set_meters(meters);
00159 edit_panel->create_objects();
00160
00161
00162
00163
00164
00165 zoom_panel = new CWindowZoom(mwindow,
00166 this,
00167 mwindow->theme->czoom_x,
00168 mwindow->theme->czoom_y);
00169 zoom_panel->create_objects();
00170 zoom_panel->zoom_text->add_item(new BC_MenuItem(AUTO_ZOOM));
00171 if(!mwindow->edl->session->cwindow_scrollbars) zoom_panel->set_text(AUTO_ZOOM);
00172
00173
00174
00175
00176
00177
00178
00179
00180 tool_panel = new CWindowTool(mwindow, this);
00181 tool_panel->Thread::start();
00182
00183 set_operation(mwindow->edl->session->cwindow_operation);
00184
00185
00186 canvas->draw_refresh();
00187
00188 draw_status();
00189
00190 return 0;
00191 }
00192
00193 int CWindowGUI::translation_event()
00194 {
00195 mwindow->session->cwindow_x = get_x();
00196 mwindow->session->cwindow_y = get_y();
00197 return 0;
00198 }
00199
00200 int CWindowGUI::resize_event(int w, int h)
00201 {
00202 mwindow->session->cwindow_x = get_x();
00203 mwindow->session->cwindow_y = get_y();
00204 mwindow->session->cwindow_w = w;
00205 mwindow->session->cwindow_h = h;
00206
00207 mwindow->theme->get_cwindow_sizes(this, mwindow->session->cwindow_controls);
00208 mwindow->theme->draw_cwindow_bg(this);
00209 flash();
00210
00211 composite_panel->reposition_buttons(mwindow->theme->ccomposite_x,
00212 mwindow->theme->ccomposite_y);
00213
00214 canvas->reposition_window(mwindow->edl,
00215 mwindow->theme->ccanvas_x,
00216 mwindow->theme->ccanvas_y,
00217 mwindow->theme->ccanvas_w,
00218 mwindow->theme->ccanvas_h);
00219
00220 timebar->resize_event();
00221
00222 slider->reposition_window(mwindow->theme->cslider_x,
00223 mwindow->theme->cslider_y,
00224 mwindow->theme->cslider_w);
00225
00226 slider->set_position();
00227
00228 transport->reposition_buttons(mwindow->theme->ctransport_x,
00229 mwindow->theme->ctransport_y);
00230
00231 edit_panel->reposition_buttons(mwindow->theme->cedit_x,
00232 mwindow->theme->cedit_y);
00233
00234
00235
00236
00237 zoom_panel->reposition_window(mwindow->theme->czoom_x,
00238 mwindow->theme->czoom_y);
00239
00240
00241
00242
00243 meters->reposition_window(mwindow->theme->cmeter_x,
00244 mwindow->theme->cmeter_y,
00245 mwindow->theme->cmeter_h);
00246
00247 draw_status();
00248
00249 BC_WindowBase::resize_event(w, h);
00250 return 1;
00251 }
00252
00253 int CWindowGUI::button_press_event()
00254 {
00255 if(canvas->get_canvas())
00256 return canvas->button_press_event_base(canvas->get_canvas());
00257 return 0;
00258 }
00259
00260 int CWindowGUI::cursor_leave_event()
00261 {
00262 if(canvas->get_canvas())
00263 return canvas->cursor_leave_event_base(canvas->get_canvas());
00264 return 0;
00265 }
00266
00267 int CWindowGUI::cursor_enter_event()
00268 {
00269 if(canvas->get_canvas())
00270 return canvas->cursor_enter_event_base(canvas->get_canvas());
00271 return 0;
00272 }
00273
00274 int CWindowGUI::button_release_event()
00275 {
00276 if(canvas->get_canvas())
00277 return canvas->button_release_event();
00278 return 0;
00279 }
00280
00281 int CWindowGUI::cursor_motion_event()
00282 {
00283 if(canvas->get_canvas())
00284 {
00285 canvas->get_canvas()->unhide_cursor();
00286 return canvas->cursor_motion_event();
00287 }
00288 return 0;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 void CWindowGUI::draw_status()
00298 {
00299 if(canvas->get_canvas() &&
00300 canvas->get_canvas()->get_video_on() ||
00301 canvas->is_processing)
00302 {
00303 draw_pixmap(active,
00304 mwindow->theme->cstatus_x,
00305 mwindow->theme->cstatus_y);
00306 }
00307 else
00308 {
00309 draw_pixmap(inactive,
00310 mwindow->theme->cstatus_x,
00311 mwindow->theme->cstatus_y);
00312 }
00313
00314 flash(mwindow->theme->cstatus_x,
00315 mwindow->theme->cstatus_y,
00316 active->get_w(),
00317 active->get_h());
00318 }
00319
00320
00321 void CWindowGUI::zoom_canvas(int do_auto, double value, int update_menu)
00322 {
00323 if(do_auto)
00324 mwindow->edl->session->cwindow_scrollbars = 0;
00325 else
00326 mwindow->edl->session->cwindow_scrollbars = 1;
00327
00328 float old_zoom = mwindow->edl->session->cwindow_zoom;
00329 float new_zoom = value;
00330 float x = canvas->w / 2;
00331 float y = canvas->h / 2;
00332 canvas->canvas_to_output(mwindow->edl,
00333 0,
00334 x,
00335 y);
00336 x -= canvas->w_visible / 2 * old_zoom / new_zoom;
00337 y -= canvas->h_visible / 2 * old_zoom / new_zoom;
00338 if(update_menu)
00339 {
00340 if(do_auto)
00341 {
00342 zoom_panel->update(AUTO_ZOOM);
00343 }
00344 else
00345 {
00346 zoom_panel->update(value);
00347 }
00348 }
00349
00350 canvas->update_zoom((int)x,
00351 (int)y,
00352 new_zoom);
00353 canvas->reposition_window(mwindow->edl,
00354 mwindow->theme->ccanvas_x,
00355 mwindow->theme->ccanvas_y,
00356 mwindow->theme->ccanvas_w,
00357 mwindow->theme->ccanvas_h);
00358 canvas->draw_refresh();
00359 }
00360
00361
00362
00363
00364
00365 void CWindowGUI::set_operation(int value)
00366 {
00367 mwindow->edl->session->cwindow_operation = value;
00368
00369 composite_panel->set_operation(value);
00370 edit_panel->update();
00371
00372 tool_panel->start_tool(value);
00373 canvas->draw_refresh();
00374 }
00375
00376 void CWindowGUI::update_tool()
00377 {
00378 tool_panel->update_values();
00379 }
00380
00381 int CWindowGUI::close_event()
00382 {
00383 cwindow->hide_window();
00384 return 1;
00385 }
00386
00387
00388 int CWindowGUI::keypress_event()
00389 {
00390 int result = 0;
00391
00392 switch(get_keypress())
00393 {
00394 case 'w':
00395 case 'W':
00396 close_event();
00397 result = 1;
00398 break;
00399 case '+':
00400 case '=':
00401 keyboard_zoomin();
00402 result = 1;
00403 break;
00404 case '-':
00405 keyboard_zoomout();
00406 result = 1;
00407 break;
00408 case 'f':
00409 unlock_window();
00410 if(mwindow->session->cwindow_fullscreen)
00411 canvas->stop_fullscreen();
00412 else
00413 canvas->start_fullscreen();
00414 lock_window("CWindowGUI::keypress_event 1");
00415 break;
00416 case ESC:
00417 unlock_window();
00418 if(mwindow->session->cwindow_fullscreen)
00419 canvas->stop_fullscreen();
00420 lock_window("CWindowGUI::keypress_event 2");
00421 break;
00422 case LEFT:
00423 if(!ctrl_down())
00424 {
00425 if (alt_down())
00426 {
00427 int shift_down = this->shift_down();
00428 unlock_window();
00429 mwindow->gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
00430
00431 mwindow->gui->lock_window("CWindowGUI::keypress_event 2");
00432 mwindow->prev_edit_handle(shift_down);
00433 mwindow->gui->unlock_window();
00434
00435 lock_window("CWindowGUI::keypress_event 1");
00436 }
00437 else
00438 {
00439 mwindow->move_left();
00440 }
00441 result = 1;
00442 }
00443 break;
00444 case RIGHT:
00445 if(!ctrl_down())
00446 {
00447 if (alt_down())
00448 {
00449 int shift_down = this->shift_down();
00450 unlock_window();
00451 mwindow->gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
00452
00453 mwindow->gui->lock_window("CWindowGUI::keypress_event 2");
00454 mwindow->next_edit_handle(shift_down);
00455 mwindow->gui->unlock_window();
00456
00457 lock_window("CWindowGUI::keypress_event 2");
00458 }
00459 else
00460 mwindow->move_right();
00461 result = 1;
00462 }
00463 break;
00464 }
00465
00466 if(!result) result = transport->keypress_event();
00467
00468 return result;
00469 }
00470
00471
00472 void CWindowGUI::reset_affected()
00473 {
00474 affected_x = 0;
00475 affected_y = 0;
00476 affected_z = 0;
00477 }
00478
00479 void CWindowGUI::keyboard_zoomin()
00480 {
00481
00482
00483 zoom_panel->zoom_tumbler->handle_up_event();
00484
00485
00486
00487
00488 }
00489
00490 void CWindowGUI::keyboard_zoomout()
00491 {
00492
00493
00494 zoom_panel->zoom_tumbler->handle_down_event();
00495
00496
00497
00498
00499 }
00500
00501
00502 void CWindowGUI::drag_motion()
00503 {
00504 if(get_hidden()) return;
00505
00506 if(mwindow->session->current_operation == DRAG_ASSET ||
00507 mwindow->session->current_operation == DRAG_VTRANSITION ||
00508 mwindow->session->current_operation == DRAG_VEFFECT)
00509 {
00510 int old_status = mwindow->session->ccanvas_highlighted;
00511 int cursor_x = get_relative_cursor_x();
00512 int cursor_y = get_relative_cursor_y();
00513
00514 mwindow->session->ccanvas_highlighted = get_cursor_over_window() &&
00515 cursor_x >= canvas->x &&
00516 cursor_x < canvas->x + canvas->w &&
00517 cursor_y >= canvas->y &&
00518 cursor_y < canvas->y + canvas->h;
00519
00520
00521 if(old_status != mwindow->session->ccanvas_highlighted)
00522 canvas->draw_refresh();
00523 }
00524 }
00525
00526 int CWindowGUI::drag_stop()
00527 {
00528 int result = 0;
00529 if(get_hidden()) return 0;
00530
00531 if((mwindow->session->current_operation == DRAG_ASSET ||
00532 mwindow->session->current_operation == DRAG_VTRANSITION ||
00533 mwindow->session->current_operation == DRAG_VEFFECT) &&
00534 mwindow->session->ccanvas_highlighted)
00535 {
00536
00537 mwindow->session->ccanvas_highlighted = 0;
00538 canvas->draw_refresh();
00539 result = 1;
00540 }
00541 else
00542 return 0;
00543
00544 if(mwindow->session->current_operation == DRAG_ASSET)
00545 {
00546 if(mwindow->session->drag_assets->total)
00547 {
00548 mwindow->gui->lock_window("CWindowGUI::drag_stop 1");
00549 mwindow->clear(0);
00550 mwindow->load_assets(mwindow->session->drag_assets,
00551 mwindow->edl->local_session->get_selectionstart(),
00552 LOAD_PASTE,
00553 mwindow->session->track_highlighted,
00554 0,
00555 mwindow->edl->session->labels_follow_edits,
00556 mwindow->edl->session->plugins_follow_edits,
00557 0);
00558 }
00559
00560 if(mwindow->session->drag_clips->total)
00561 {
00562 mwindow->gui->lock_window("CWindowGUI::drag_stop 2");
00563 mwindow->clear(0);
00564 mwindow->paste_edls(mwindow->session->drag_clips,
00565 LOAD_PASTE,
00566 mwindow->session->track_highlighted,
00567 mwindow->edl->local_session->get_selectionstart(),
00568 mwindow->edl->session->labels_follow_edits,
00569 mwindow->edl->session->plugins_follow_edits,
00570 0);
00571 }
00572
00573 if(mwindow->session->drag_assets->total ||
00574 mwindow->session->drag_clips->total)
00575 {
00576 mwindow->save_backup();
00577 mwindow->restart_brender();
00578 mwindow->gui->update(1, 1, 1, 1, 0, 1, 0);
00579 mwindow->undo->update_undo(_("insert assets"), LOAD_ALL);
00580 mwindow->gui->unlock_window();
00581 mwindow->sync_parameters(LOAD_ALL);
00582 }
00583 }
00584
00585 if(mwindow->session->current_operation == DRAG_VEFFECT)
00586 {
00587
00588 Track *affected_track = cwindow->calculate_affected_track();
00589
00590
00591 mwindow->gui->lock_window("CWindowGUI::drag_stop 3");
00592 mwindow->insert_effects_cwindow(affected_track);
00593 mwindow->session->current_operation = NO_OPERATION;
00594 mwindow->gui->unlock_window();
00595 }
00596
00597 if(mwindow->session->current_operation == DRAG_VTRANSITION)
00598 {
00599 Track *affected_track = cwindow->calculate_affected_track();
00600 mwindow->gui->lock_window("CWindowGUI::drag_stop 4");
00601 mwindow->paste_transition_cwindow(affected_track);
00602 mwindow->session->current_operation = NO_OPERATION;
00603 mwindow->gui->unlock_window();
00604 }
00605
00606 return result;
00607 }
00608
00609
00610 CWindowEditing::CWindowEditing(MWindow *mwindow, CWindow *cwindow)
00611 : EditPanel(mwindow,
00612 cwindow->gui,
00613 mwindow->theme->cedit_x,
00614 mwindow->theme->cedit_y,
00615 mwindow->edl->session->editing_mode,
00616 0,
00617 1,
00618 0,
00619 0,
00620 1,
00621 1,
00622 1,
00623 1,
00624 1,
00625 0,
00626 0,
00627 1,
00628 1,
00629 1,
00630 0,
00631 1)
00632 {
00633 this->mwindow = mwindow;
00634 this->cwindow = cwindow;
00635 }
00636
00637 void CWindowEditing::set_inpoint()
00638 {
00639 mwindow->set_inpoint(0);
00640 }
00641
00642 void CWindowEditing::set_outpoint()
00643 {
00644 mwindow->set_outpoint(0);
00645 }
00646
00647
00648
00649
00650
00651 CWindowMeters::CWindowMeters(MWindow *mwindow, CWindowGUI *gui, int x, int y, int h)
00652 : MeterPanel(mwindow,
00653 gui,
00654 x,
00655 y,
00656 h,
00657 mwindow->edl->session->audio_channels,
00658 mwindow->edl->session->cwindow_meter)
00659 {
00660 this->mwindow = mwindow;
00661 this->gui = gui;
00662 }
00663
00664 CWindowMeters::~CWindowMeters()
00665 {
00666 }
00667
00668 int CWindowMeters::change_status_event()
00669 {
00670 mwindow->edl->session->cwindow_meter = use_meters;
00671 mwindow->theme->get_cwindow_sizes(gui, mwindow->session->cwindow_controls);
00672 gui->resize_event(gui->get_w(), gui->get_h());
00673 return 1;
00674 }
00675
00676
00677
00678
00679 CWindowZoom::CWindowZoom(MWindow *mwindow, CWindowGUI *gui, int x, int y)
00680 : ZoomPanel(mwindow,
00681 gui,
00682 (double)mwindow->edl->session->cwindow_zoom,
00683 x,
00684 y,
00685 80,
00686 my_zoom_table,
00687 total_zooms,
00688 ZOOM_PERCENTAGE)
00689 {
00690 this->mwindow = mwindow;
00691 this->gui = gui;
00692 }
00693
00694 CWindowZoom::~CWindowZoom()
00695 {
00696 }
00697
00698 int CWindowZoom::handle_event()
00699 {
00700 if(!strcasecmp(AUTO_ZOOM, get_text()))
00701 {
00702 gui->zoom_canvas(1, get_value(), 0);
00703 }
00704 else
00705 {
00706 gui->zoom_canvas(0, get_value(), 0);
00707 }
00708
00709 return 1;
00710 }
00711
00712
00713
00714 CWindowSlider::CWindowSlider(MWindow *mwindow, CWindow *cwindow, int x, int y, int pixels)
00715 : BC_PercentageSlider(x,
00716 y,
00717 0,
00718 pixels,
00719 pixels,
00720 0,
00721 1,
00722 0)
00723 {
00724 this->mwindow = mwindow;
00725 this->cwindow = cwindow;
00726 set_precision(0.00001);
00727 set_pagination(1.0, 10.0);
00728 }
00729
00730 CWindowSlider::~CWindowSlider()
00731 {
00732 }
00733
00734 int CWindowSlider::handle_event()
00735 {
00736 unlock_window();
00737 cwindow->playback_engine->interrupt_playback(1);
00738 lock_window("CWindowSlider::handle_event 1");
00739
00740 mwindow->gui->lock_window("CWindowSlider::handle_event 2");
00741 mwindow->select_point((double)get_value());
00742 mwindow->gui->unlock_window();
00743 return 1;
00744 }
00745
00746 void CWindowSlider::set_position()
00747 {
00748 double new_length = mwindow->edl->tracks->total_playable_length();
00749 if(mwindow->edl->local_session->preview_end <= 0 ||
00750 mwindow->edl->local_session->preview_end > new_length)
00751 mwindow->edl->local_session->preview_end = new_length;
00752 if(mwindow->edl->local_session->preview_start >
00753 mwindow->edl->local_session->preview_end)
00754 mwindow->edl->local_session->preview_start = 0;
00755
00756
00757
00758 update(mwindow->theme->cslider_w,
00759 mwindow->edl->local_session->get_selectionstart(1),
00760 mwindow->edl->local_session->preview_start,
00761 mwindow->edl->local_session->preview_end);
00762 }
00763
00764
00765 int CWindowSlider::increase_value()
00766 {
00767 unlock_window();
00768 cwindow->gui->transport->handle_transport(SINGLE_FRAME_FWD);
00769 lock_window("CWindowSlider::increase_value");
00770 return 1;
00771 }
00772
00773 int CWindowSlider::decrease_value()
00774 {
00775 unlock_window();
00776 cwindow->gui->transport->handle_transport(SINGLE_FRAME_REWIND);
00777 lock_window("CWindowSlider::decrease_value");
00778 return 1;
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 CWindowTransport::CWindowTransport(MWindow *mwindow,
00806 CWindowGUI *gui,
00807 int x,
00808 int y)
00809 : PlayTransport(mwindow,
00810 gui,
00811 x,
00812 y)
00813 {
00814 this->gui = gui;
00815 }
00816
00817 EDL* CWindowTransport::get_edl()
00818 {
00819 return mwindow->edl;
00820 }
00821
00822 void CWindowTransport::goto_start()
00823 {
00824 gui->unlock_window();
00825 handle_transport(REWIND, 1);
00826
00827 mwindow->gui->lock_window("CWindowTransport::goto_start 1");
00828 mwindow->goto_start();
00829 mwindow->gui->unlock_window();
00830
00831 gui->lock_window("CWindowTransport::goto_start 2");
00832 }
00833
00834 void CWindowTransport::goto_end()
00835 {
00836 gui->unlock_window();
00837 handle_transport(GOTO_END, 1);
00838
00839 mwindow->gui->lock_window("CWindowTransport::goto_end 1");
00840 mwindow->goto_end();
00841 mwindow->gui->unlock_window();
00842
00843 gui->lock_window("CWindowTransport::goto_end 2");
00844 }
00845
00846
00847
00848 CWindowCanvas::CWindowCanvas(MWindow *mwindow, CWindowGUI *gui)
00849 : Canvas(mwindow,
00850 gui,
00851 mwindow->theme->ccanvas_x,
00852 mwindow->theme->ccanvas_y,
00853 mwindow->theme->ccanvas_w,
00854 mwindow->theme->ccanvas_h,
00855 0,
00856 0,
00857 mwindow->edl->session->cwindow_scrollbars,
00858 1)
00859 {
00860 this->mwindow = mwindow;
00861 this->gui = gui;
00862 }
00863
00864 void CWindowCanvas::status_event()
00865 {
00866 gui->draw_status();
00867 }
00868
00869 int CWindowCanvas::get_fullscreen()
00870 {
00871 return mwindow->session->cwindow_fullscreen;
00872 }
00873
00874 void CWindowCanvas::set_fullscreen(int value)
00875 {
00876 mwindow->session->cwindow_fullscreen = value;
00877 }
00878
00879
00880 void CWindowCanvas::update_zoom(int x, int y, float zoom)
00881 {
00882 use_scrollbars = mwindow->edl->session->cwindow_scrollbars;
00883
00884 mwindow->edl->session->cwindow_xscroll = x;
00885 mwindow->edl->session->cwindow_yscroll = y;
00886 mwindow->edl->session->cwindow_zoom = zoom;
00887 }
00888
00889 void CWindowCanvas::zoom_auto()
00890 {
00891 gui->zoom_canvas(1, 1.0, 1);
00892 }
00893
00894 int CWindowCanvas::get_xscroll()
00895 {
00896 return mwindow->edl->session->cwindow_xscroll;
00897 }
00898
00899 int CWindowCanvas::get_yscroll()
00900 {
00901 return mwindow->edl->session->cwindow_yscroll;
00902 }
00903
00904
00905 float CWindowCanvas::get_zoom()
00906 {
00907 return mwindow->edl->session->cwindow_zoom;
00908 }
00909
00910 void CWindowCanvas::draw_refresh()
00911 {
00912 if(get_canvas() && !get_canvas()->get_video_on())
00913 {
00914
00915 if(refresh_frame)
00916 {
00917 float in_x1, in_y1, in_x2, in_y2;
00918 float out_x1, out_y1, out_x2, out_y2;
00919 get_transfers(mwindow->edl,
00920 in_x1,
00921 in_y1,
00922 in_x2,
00923 in_y2,
00924 out_x1,
00925 out_y1,
00926 out_x2,
00927 out_y2);
00928
00929 get_canvas()->clear_box(0,
00930 0,
00931 get_canvas()->get_w(),
00932 get_canvas()->get_h());
00933
00934
00935
00936
00937
00938 if(out_x2 > out_x1 &&
00939 out_y2 > out_y1 &&
00940 in_x2 > in_x1 &&
00941 in_y2 > in_y1)
00942 {
00943
00944
00945 get_canvas()->draw_vframe(refresh_frame,
00946 (int)out_x1,
00947 (int)out_y1,
00948 (int)(out_x2 - out_x1),
00949 (int)(out_y2 - out_y1),
00950 (int)in_x1,
00951 (int)in_y1,
00952 (int)(in_x2 - in_x1),
00953 (int)(in_y2 - in_y1),
00954 0);
00955 }
00956 }
00957
00958 draw_overlays();
00959 get_canvas()->flash();
00960 }
00961
00962 }
00963
00964 #define CROPHANDLE_W 10
00965 #define CROPHANDLE_H 10
00966
00967 void CWindowCanvas::draw_crophandle(int x, int y)
00968 {
00969 get_canvas()->draw_box(x, y, CROPHANDLE_W, CROPHANDLE_H);
00970 }
00971
00972 #define CONTROL_W 10
00973 #define CONTROL_H 10
00974 #define FIRST_CONTROL_W 20
00975 #define FIRST_CONTROL_H 20
00976 #undef BC_INFINITY
00977 #define BC_INFINITY 65536
00978 #ifndef SQR
00979 #define SQR(x) ((x) * (x))
00980 #endif
00981
00982 int CWindowCanvas::do_mask(int &redraw,
00983 int &rerender,
00984 int button_press,
00985 int cursor_motion,
00986 int draw)
00987 {
00988
00989
00990 Track *track = gui->cwindow->calculate_affected_track();
00991
00992
00993 if(!track) return 0;
00994
00995
00996 MaskAutos *mask_autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
00997 int64_t position = track->to_units(
00998 mwindow->edl->local_session->get_selectionstart(1),
00999 0);
01000 ArrayList<MaskPoint*> points;
01001 mask_autos->get_points(&points, mwindow->edl->session->cwindow_mask,
01002 position,
01003 PLAY_FORWARD);
01004
01005
01006
01007 float half_track_w = (float)track->track_w / 2;
01008 float half_track_h = (float)track->track_h / 2;
01009
01010 float projector_x, projector_y, projector_z;
01011 track->automation->get_projector(&projector_x,
01012 &projector_y,
01013 &projector_z,
01014 position,
01015 PLAY_FORWARD);
01016
01017
01018
01019 float mask_cursor_x = get_cursor_x();
01020 float mask_cursor_y = get_cursor_y();
01021 canvas_to_output(mwindow->edl, 0, mask_cursor_x, mask_cursor_y);
01022
01023 projector_x += mwindow->edl->session->output_w / 2;
01024 projector_y += mwindow->edl->session->output_h / 2;
01025
01026 mask_cursor_x -= projector_x;
01027 mask_cursor_y -= projector_y;
01028 mask_cursor_x = mask_cursor_x / projector_z + half_track_w;
01029 mask_cursor_y = mask_cursor_y / projector_z + half_track_h;
01030
01031
01032 if(button_press)
01033 {
01034 gui->x_origin = mask_cursor_x;
01035 gui->y_origin = mask_cursor_y;
01036 }
01037
01038 int result = 0;
01039
01040 int shortest_point1 = -1;
01041 int shortest_point2 = -1;
01042
01043 int shortest_point = -1;
01044
01045 float shortest_line_distance = BC_INFINITY;
01046
01047 float shortest_point_distance = BC_INFINITY;
01048 int selected_point = -1;
01049 int selected_control_point = -1;
01050 float selected_control_point_distance = BC_INFINITY;
01051 ArrayList<int> x_points;
01052 ArrayList<int> y_points;
01053
01054 if(!cursor_motion)
01055 {
01056 if(draw)
01057 {
01058 get_canvas()->set_color(WHITE);
01059 get_canvas()->set_inverse();
01060 }
01061
01062
01063
01064
01065 for(int i = 0; i < points.total && !result; i++)
01066 {
01067 MaskPoint *point1 = points.values[i];
01068 MaskPoint *point2 = (i >= points.total - 1) ?
01069 points.values[0] :
01070 points.values[i + 1];
01071 float x0, x1, x2, x3;
01072 float y0, y1, y2, y3;
01073 float old_x, old_y, x, y;
01074 int segments = (int)(sqrt(SQR(point1->x - point2->x) + SQR(point1->y - point2->y)));
01075
01076
01077
01078 for(int j = 0; j <= segments && !result; j++)
01079 {
01080
01081 x0 = point1->x;
01082 y0 = point1->y;
01083 x1 = point1->x + point1->control_x2;
01084 y1 = point1->y + point1->control_y2;
01085 x2 = point2->x + point2->control_x1;
01086 y2 = point2->y + point2->control_y1;
01087 x3 = point2->x;
01088 y3 = point2->y;
01089
01090 float t = (float)j / segments;
01091 float tpow2 = t * t;
01092 float tpow3 = t * t * t;
01093 float invt = 1 - t;
01094 float invtpow2 = invt * invt;
01095 float invtpow3 = invt * invt * invt;
01096
01097 x = ( invtpow3 * x0
01098 + 3 * t * invtpow2 * x1
01099 + 3 * tpow2 * invt * x2
01100 + tpow3 * x3);
01101 y = ( invtpow3 * y0
01102 + 3 * t * invtpow2 * y1
01103 + 3 * tpow2 * invt * y2
01104 + tpow3 * y3);
01105
01106 x = (x - half_track_w) * projector_z + projector_x;
01107 y = (y - half_track_h) * projector_z + projector_y;
01108
01109
01110
01111 if(button_press)
01112 {
01113 float line_distance =
01114 sqrt(SQR(x - mask_cursor_x) + SQR(y - mask_cursor_y));
01115
01116
01117
01118 if(line_distance < shortest_line_distance ||
01119 shortest_point1 < 0)
01120 {
01121 shortest_line_distance = line_distance;
01122 shortest_point1 = i;
01123 shortest_point2 = (i >= points.total - 1) ? 0 : (i + 1);
01124
01125 }
01126
01127
01128 float point_distance1 =
01129 sqrt(SQR(point1->x - mask_cursor_x) + SQR(point1->y - mask_cursor_y));
01130 float point_distance2 =
01131 sqrt(SQR(point2->x - mask_cursor_x) + SQR(point2->y - mask_cursor_y));
01132
01133 if(point_distance1 < shortest_point_distance ||
01134 shortest_point < 0)
01135 {
01136 shortest_point_distance = point_distance1;
01137 shortest_point = i;
01138 }
01139
01140 if(point_distance2 < shortest_point_distance ||
01141 shortest_point < 0)
01142 {
01143 shortest_point_distance = point_distance2;
01144 shortest_point = (i >= points.total - 1) ? 0 : (i + 1);
01145 }
01146 }
01147
01148 output_to_canvas(mwindow->edl, 0, x, y);
01149
01150
01151 #define TEST_BOX(cursor_x, cursor_y, target_x, target_y) \
01152 (cursor_x >= target_x - CONTROL_W / 2 && \
01153 cursor_x < target_x + CONTROL_W / 2 && \
01154 cursor_y >= target_y - CONTROL_H / 2 && \
01155 cursor_y < target_y + CONTROL_H / 2)
01156
01157
01158 if(button_press)
01159 {
01160 float canvas_x = (x0 - half_track_w) * projector_z + projector_x;
01161 float canvas_y = (y0 - half_track_h) * projector_z + projector_y;
01162 int cursor_x = get_cursor_x();
01163 int cursor_y = get_cursor_y();
01164
01165
01166 if(gui->shift_down())
01167 {
01168 float control_x = (x1 - half_track_w) * projector_z + projector_x;
01169 float control_y = (y1 - half_track_h) * projector_z + projector_y;
01170 output_to_canvas(mwindow->edl, 0, control_x, control_y);
01171
01172 float distance =
01173 sqrt(SQR(control_x - cursor_x) + SQR(control_y - cursor_y));
01174
01175 if(distance < selected_control_point_distance)
01176 {
01177 selected_point = i;
01178 selected_control_point = 1;
01179 selected_control_point_distance = distance;
01180 }
01181 }
01182 else
01183 {
01184 output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
01185 if(!gui->ctrl_down())
01186 {
01187 if(TEST_BOX(cursor_x, cursor_y, canvas_x, canvas_y))
01188 {
01189 selected_point = i;
01190 }
01191 }
01192 else
01193 {
01194 selected_point = shortest_point;
01195 }
01196 }
01197
01198
01199 canvas_x = (x3 - half_track_w) * projector_z + projector_x;
01200 canvas_y = (y3 - half_track_h) * projector_z + projector_y;
01201 if(gui->shift_down())
01202 {
01203 float control_x = (x2 - half_track_w) * projector_z + projector_x;
01204 float control_y = (y2 - half_track_h) * projector_z + projector_y;
01205 output_to_canvas(mwindow->edl, 0, control_x, control_y);
01206
01207 float distance =
01208 sqrt(SQR(control_x - cursor_x) + SQR(control_y - cursor_y));
01209
01210
01211 if(distance < selected_control_point_distance)
01212 {
01213 selected_point = (i < points.total - 1 ? i + 1 : 0);
01214 selected_control_point = 0;
01215 selected_control_point_distance = distance;
01216 }
01217 }
01218 else
01219 if(i < points.total - 1)
01220 {
01221 output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
01222 if(!gui->ctrl_down())
01223 {
01224 if(TEST_BOX(cursor_x, cursor_y, canvas_x, canvas_y))
01225 {
01226 selected_point = (i < points.total - 1 ? i + 1 : 0);
01227 }
01228 }
01229 else
01230 {
01231 selected_point = shortest_point;
01232 }
01233 }
01234 }
01235
01236
01237
01238 if(j > 0)
01239 {
01240
01241 if(draw)
01242 {
01243 x_points.append((int)x);
01244 y_points.append((int)y);
01245 }
01246
01247 if(j == segments)
01248 {
01249
01250
01251
01252
01253 if(draw)
01254 {
01255
01256 if(i < points.total - 1)
01257 {
01258 if(i == gui->affected_point - 1)
01259 get_canvas()->draw_disc((int)x - CONTROL_W / 2,
01260 (int)y - CONTROL_W / 2,
01261 CONTROL_W,
01262 CONTROL_W);
01263 else
01264 get_canvas()->draw_circle((int)x - CONTROL_W / 2,
01265 (int)y - CONTROL_W / 2,
01266 CONTROL_W,
01267 CONTROL_W);
01268
01269
01270
01271 }
01272
01273
01274 x2 = (x2 - half_track_w) * projector_z + projector_x;
01275 y2 = (y2 - half_track_h) * projector_z + projector_y;
01276 output_to_canvas(mwindow->edl, 0, x2, y2);
01277 get_canvas()->draw_line((int)x, (int)y, (int)x2, (int)y2);
01278 get_canvas()->draw_rectangle((int)x2 - CONTROL_W / 2,
01279 (int)y2 - CONTROL_H / 2,
01280 CONTROL_W,
01281 CONTROL_H);
01282 }
01283 }
01284 }
01285 else
01286 {
01287
01288
01289
01290 if(i == 0 && draw)
01291 {
01292 get_canvas()->draw_disc((int)x - FIRST_CONTROL_W / 2,
01293 (int)y - FIRST_CONTROL_H / 2,
01294 FIRST_CONTROL_W,
01295 FIRST_CONTROL_H);
01296 }
01297
01298
01299 if(draw)
01300 {
01301 x1 = (x1 - half_track_w) * projector_z + projector_x;
01302 y1 = (y1 - half_track_h) * projector_z + projector_y;
01303 output_to_canvas(mwindow->edl, 0, x1, y1);
01304 get_canvas()->draw_line((int)x, (int)y, (int)x1, (int)y1);
01305 get_canvas()->draw_rectangle((int)x1 - CONTROL_W / 2,
01306 (int)y1 - CONTROL_H / 2,
01307 CONTROL_W,
01308 CONTROL_H);
01309
01310 x_points.append((int)x);
01311 y_points.append((int)y);
01312 }
01313 }
01314
01315
01316 old_x = x;
01317 old_y = y;
01318 }
01319 }
01320
01321
01322 if(draw)
01323 {
01324 get_canvas()->draw_polygon(&x_points, &y_points);
01325 get_canvas()->set_opaque();
01326 }
01327
01328 }
01329
01330
01331
01332
01333
01334
01335
01336 if(button_press && !result)
01337 {
01338 gui->affected_track = gui->cwindow->calculate_affected_track();
01339
01340 if(gui->affected_track)
01341 gui->affected_keyframe =
01342 gui->cwindow->calculate_affected_auto(
01343 gui->affected_track->automation->autos[AUTOMATION_MASK],
01344 1);
01345
01346 MaskAuto *keyframe = (MaskAuto*)gui->affected_keyframe;
01347 SubMask *mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
01348
01349
01350
01351 if(gui->alt_down() && mask->points.total)
01352 {
01353 gui->current_operation = CWINDOW_MASK_TRANSLATE;
01354 gui->affected_point = 0;
01355 }
01356 else
01357
01358 if(selected_point >= 0)
01359 {
01360 gui->affected_point = selected_point;
01361
01362 if(selected_control_point == 0)
01363 gui->current_operation = CWINDOW_MASK_CONTROL_IN;
01364 else
01365 if(selected_control_point == 1)
01366 gui->current_operation = CWINDOW_MASK_CONTROL_OUT;
01367 else
01368 gui->current_operation = mwindow->edl->session->cwindow_operation;
01369 }
01370 else
01371
01372 if(!gui->shift_down() && !gui->alt_down())
01373 {
01374
01375 MaskPoint *point = new MaskPoint;
01376 point->x = mask_cursor_x;
01377 point->y = mask_cursor_y;
01378 point->control_x1 = 0;
01379 point->control_y1 = 0;
01380 point->control_x2 = 0;
01381 point->control_y2 = 0;
01382
01383
01384 if(shortest_point2 < shortest_point1)
01385 {
01386 shortest_point2 ^= shortest_point1;
01387 shortest_point1 ^= shortest_point2;
01388 shortest_point2 ^= shortest_point1;
01389 }
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404 if(labs(shortest_point1 - shortest_point2) > 1)
01405 {
01406
01407 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
01408 current; )
01409 {
01410 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
01411 MaskPoint *new_point = new MaskPoint;
01412 submask->points.append(new_point);
01413 *new_point = *point;
01414 if(current == (MaskAuto*)mask_autos->default_auto)
01415 current = (MaskAuto*)mask_autos->first;
01416 else
01417 current = (MaskAuto*)NEXT;
01418 }
01419
01420 gui->affected_point = mask->points.total - 1;
01421 result = 1;
01422 }
01423 else
01424
01425 if(shortest_point1 >= 0 && shortest_point2 >= 0)
01426 {
01427 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
01428 current; )
01429 {
01430 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
01431
01432
01433 if(submask->points.total >= shortest_point2)
01434 {
01435 MaskPoint *new_point = new MaskPoint;
01436 submask->points.append(0);
01437 for(int i = submask->points.total - 1;
01438 i > shortest_point2;
01439 i--)
01440 submask->points.values[i] = submask->points.values[i - 1];
01441 submask->points.values[shortest_point2] = new_point;
01442
01443 *new_point = *point;
01444 }
01445
01446 if(current == (MaskAuto*)mask_autos->default_auto)
01447 current = (MaskAuto*)mask_autos->first;
01448 else
01449 current = (MaskAuto*)NEXT;
01450 }
01451
01452
01453 gui->affected_point = shortest_point2;
01454 result = 1;
01455 }
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466 if(!result)
01467 {
01468
01469 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
01470 current; )
01471 {
01472 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
01473 MaskPoint *new_point = new MaskPoint;
01474 submask->points.append(new_point);
01475 *new_point = *point;
01476 if(current == (MaskAuto*)mask_autos->default_auto)
01477 current = (MaskAuto*)mask_autos->first;
01478 else
01479 current = (MaskAuto*)NEXT;
01480 }
01481
01482
01483
01484 if(mask->points.total < 2)
01485 {
01486 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
01487 current; )
01488 {
01489 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
01490 MaskPoint *new_point = new MaskPoint;
01491 submask->points.append(new_point);
01492 *new_point = *point;
01493 if(current == (MaskAuto*)mask_autos->default_auto)
01494 current = (MaskAuto*)mask_autos->first;
01495 else
01496 current = (MaskAuto*)NEXT;
01497 }
01498 }
01499 gui->affected_point = mask->points.total - 1;
01500
01501 }
01502
01503
01504
01505 gui->current_operation = mwindow->edl->session->cwindow_operation;
01506
01507 delete point;
01508
01509 mwindow->undo->update_undo(_("mask point"), LOAD_AUTOMATION);
01510
01511
01512 }
01513
01514 result = 1;
01515 rerender = 1;
01516 redraw = 1;
01517 }
01518
01519 if(button_press && result)
01520 {
01521 MaskAuto *keyframe = (MaskAuto*)gui->affected_keyframe;
01522 SubMask *mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
01523 MaskPoint *point = mask->points.values[gui->affected_point];
01524 gui->center_x = point->x;
01525 gui->center_y = point->y;
01526 gui->control_in_x = point->control_x1;
01527 gui->control_in_y = point->control_y1;
01528 gui->control_out_x = point->control_x2;
01529 gui->control_out_y = point->control_y2;
01530 }
01531
01532
01533 if(cursor_motion)
01534 {
01535 MaskAuto *keyframe = (MaskAuto*)gui->affected_keyframe;
01536 SubMask *mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
01537 if(gui->affected_point < mask->points.total)
01538 {
01539 MaskPoint *point = mask->points.values[gui->affected_point];
01540
01541
01542
01543 float cursor_x = mask_cursor_x;
01544 float cursor_y = mask_cursor_y;
01545
01546
01547 float last_x = point->x;
01548 float last_y = point->y;
01549 float last_control_x1 = point->control_x1;
01550 float last_control_y1 = point->control_y1;
01551 float last_control_x2 = point->control_x2;
01552 float last_control_y2 = point->control_y2;
01553
01554
01555 switch(gui->current_operation)
01556 {
01557 case CWINDOW_MASK:
01558 point->x = cursor_x - gui->x_origin + gui->center_x;
01559 point->y = cursor_y - gui->y_origin + gui->center_y;
01560 break;
01561
01562 case CWINDOW_MASK_CONTROL_IN:
01563 point->control_x1 = cursor_x - gui->x_origin + gui->control_in_x;
01564 point->control_y1 = cursor_y - gui->y_origin + gui->control_in_y;
01565 break;
01566
01567 case CWINDOW_MASK_CONTROL_OUT:
01568 point->control_x2 = cursor_x - gui->x_origin + gui->control_out_x;
01569 point->control_y2 = cursor_y - gui->y_origin + gui->control_out_y;
01570 break;
01571
01572 case CWINDOW_MASK_TRANSLATE:
01573 for(int i = 0; i < mask->points.total; i++)
01574 {
01575 mask->points.values[i]->x += cursor_x - gui->x_origin;
01576 mask->points.values[i]->y += cursor_y - gui->y_origin;
01577 }
01578 gui->x_origin = cursor_x;
01579 gui->y_origin = cursor_y;
01580 break;
01581 }
01582
01583
01584 if( !EQUIV(last_x, point->x) ||
01585 !EQUIV(last_y, point->y) ||
01586 !EQUIV(last_control_x1, point->control_x1) ||
01587 !EQUIV(last_control_y1, point->control_y1) ||
01588 !EQUIV(last_control_x2, point->control_x2) ||
01589 !EQUIV(last_control_y2, point->control_y2))
01590 {
01591 rerender = 1;
01592 redraw = 1;
01593 }
01594 }
01595 result = 1;
01596 }
01597
01598
01599 points.remove_all_objects();
01600
01601 return result;
01602 }
01603
01604
01605 int CWindowCanvas::do_eyedrop(int &rerender, int button_press)
01606 {
01607 int result = 0;
01608 float cursor_x = get_cursor_x();
01609 float cursor_y = get_cursor_y();
01610
01611
01612 if(button_press)
01613 {
01614 gui->current_operation = CWINDOW_EYEDROP;
01615 }
01616
01617 if(gui->current_operation == CWINDOW_EYEDROP)
01618 {
01619 canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
01620
01621
01622
01623 if(refresh_frame)
01624 {
01625 CLAMP(cursor_x, 0, refresh_frame->get_w() - 1);
01626 CLAMP(cursor_y, 0, refresh_frame->get_h() - 1);
01627
01628
01629 #define V_TO_R 1.40200
01630 #define V_TO_G -0.71414
01631
01632 #define U_TO_G -0.34414
01633 #define U_TO_B 1.77200
01634
01635 #define GET_COLOR(type, components, max, do_yuv) \
01636 { \
01637 type *row = (type*)(refresh_frame->get_rows()[(int)cursor_y]) + \
01638 (int)cursor_x * components; \
01639 float red = (float)*row++ / max; \
01640 float green = (float)*row++ / max; \
01641 float blue = (float)*row++ / max; \
01642 if(do_yuv) \
01643 { \
01644 mwindow->edl->local_session->red = red + V_TO_R * (blue - 0.5); \
01645 mwindow->edl->local_session->green = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \
01646 mwindow->edl->local_session->blue = red + U_TO_B * (green - 0.5); \
01647 } \
01648 else \
01649 { \
01650 mwindow->edl->local_session->red = red; \
01651 mwindow->edl->local_session->green = green; \
01652 mwindow->edl->local_session->blue = blue; \
01653 } \
01654 }
01655
01656 switch(refresh_frame->get_color_model())
01657 {
01658 case BC_YUV888:
01659 GET_COLOR(unsigned char, 3, 0xff, 1);
01660 break;
01661 case BC_YUVA8888:
01662 GET_COLOR(unsigned char, 4, 0xff, 1);
01663 break;
01664 case BC_YUV161616:
01665 GET_COLOR(uint16_t, 3, 0xffff, 1);
01666 break;
01667 case BC_YUVA16161616:
01668 GET_COLOR(uint16_t, 4, 0xffff, 1);
01669 break;
01670 case BC_RGB888:
01671 GET_COLOR(unsigned char, 3, 0xff, 0);
01672 break;
01673 case BC_RGBA8888:
01674 GET_COLOR(unsigned char, 4, 0xff, 0);
01675 break;
01676 case BC_RGB_FLOAT:
01677 GET_COLOR(float, 3, 1.0, 0);
01678 break;
01679 case BC_RGBA_FLOAT:
01680 GET_COLOR(float, 4, 1.0, 0);
01681 break;
01682 }
01683 }
01684 else
01685 {
01686 mwindow->edl->local_session->red = 0;
01687 mwindow->edl->local_session->green = 0;
01688 mwindow->edl->local_session->blue = 0;
01689 }
01690
01691
01692 gui->update_tool();
01693
01694
01695
01696 result = 1;
01697
01698
01699
01700 }
01701
01702 return result;
01703 }
01704
01705 void CWindowCanvas::draw_overlays()
01706 {
01707 if(mwindow->edl->session->safe_regions)
01708 {
01709 draw_safe_regions();
01710 }
01711
01712 if(mwindow->edl->session->cwindow_scrollbars)
01713 {
01714
01715 float x1, y1, x2, y2;
01716 x1 = 0;
01717 x2 = mwindow->edl->session->output_w;
01718 y1 = 0;
01719 y2 = mwindow->edl->session->output_h;
01720 output_to_canvas(mwindow->edl, 0, x1, y1);
01721 output_to_canvas(mwindow->edl, 0, x2, y2);
01722
01723 get_canvas()->set_inverse();
01724 get_canvas()->set_color(WHITE);
01725
01726 get_canvas()->draw_rectangle((int)x1,
01727 (int)y1,
01728 (int)(x2 - x1),
01729 (int)(y2 - y1));
01730
01731 get_canvas()->set_opaque();
01732 }
01733
01734 if(mwindow->session->ccanvas_highlighted)
01735 {
01736 get_canvas()->set_color(WHITE);
01737 get_canvas()->set_inverse();
01738 get_canvas()->draw_rectangle(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
01739 get_canvas()->draw_rectangle(1, 1, get_canvas()->get_w() - 2, get_canvas()->get_h() - 2);
01740 get_canvas()->set_opaque();
01741 }
01742
01743 int temp1 = 0, temp2 = 0;
01744
01745 switch(mwindow->edl->session->cwindow_operation)
01746 {
01747 case CWINDOW_CAMERA:
01748 draw_bezier(1);
01749 break;
01750
01751 case CWINDOW_PROJECTOR:
01752 draw_bezier(0);
01753 break;
01754
01755 case CWINDOW_CROP:
01756 draw_crop();
01757 break;
01758
01759 case CWINDOW_MASK:
01760 do_mask(temp1, temp2, 0, 0, 1);
01761 break;
01762 }
01763 }
01764
01765 void CWindowCanvas::draw_safe_regions()
01766 {
01767 float action_x1, action_x2, action_y1, action_y2;
01768 float title_x1, title_x2, title_y1, title_y2;
01769
01770 action_x1 = mwindow->edl->session->output_w / 2 - mwindow->edl->session->output_w / 2 * 0.9;
01771 action_x2 = mwindow->edl->session->output_w / 2 + mwindow->edl->session->output_w / 2 * 0.9;
01772 action_y1 = mwindow->edl->session->output_h / 2 - mwindow->edl->session->output_h / 2 * 0.9;
01773 action_y2 = mwindow->edl->session->output_h / 2 + mwindow->edl->session->output_h / 2 * 0.9;
01774 title_x1 = mwindow->edl->session->output_w / 2 - mwindow->edl->session->output_w / 2 * 0.8;
01775 title_x2 = mwindow->edl->session->output_w / 2 + mwindow->edl->session->output_w / 2 * 0.8;
01776 title_y1 = mwindow->edl->session->output_h / 2 - mwindow->edl->session->output_h / 2 * 0.8;
01777 title_y2 = mwindow->edl->session->output_h / 2 + mwindow->edl->session->output_h / 2 * 0.8;
01778
01779 output_to_canvas(mwindow->edl, 0, action_x1, action_y1);
01780 output_to_canvas(mwindow->edl, 0, action_x2, action_y2);
01781 output_to_canvas(mwindow->edl, 0, title_x1, title_y1);
01782 output_to_canvas(mwindow->edl, 0, title_x2, title_y2);
01783
01784 get_canvas()->set_inverse();
01785 get_canvas()->set_color(WHITE);
01786
01787 get_canvas()->draw_rectangle((int)action_x1,
01788 (int)action_y1,
01789 (int)(action_x2 - action_x1),
01790 (int)(action_y2 - action_y1));
01791 get_canvas()->draw_rectangle((int)title_x1,
01792 (int)title_y1,
01793 (int)(title_x2 - title_x1),
01794 (int)(title_y2 - title_y1));
01795
01796 get_canvas()->set_opaque();
01797 }
01798
01799 void CWindowCanvas::reset_keyframe(int do_camera)
01800 {
01801 FloatAuto *x_keyframe = 0;
01802 FloatAuto *y_keyframe = 0;
01803 FloatAuto *z_keyframe = 0;
01804 Track *affected_track = 0;
01805
01806 affected_track = gui->cwindow->calculate_affected_track();
01807
01808 if(affected_track)
01809 {
01810 gui->cwindow->calculate_affected_autos(&x_keyframe,
01811 &y_keyframe,
01812 &z_keyframe,
01813 affected_track,
01814 do_camera,
01815 1,
01816 1,
01817 1);
01818
01819 x_keyframe->value = 0;
01820 y_keyframe->value = 0;
01821 z_keyframe->value = 1;
01822
01823 mwindow->sync_parameters(CHANGE_PARAMS);
01824 gui->update_tool();
01825 }
01826 }
01827
01828 void CWindowCanvas::reset_camera()
01829 {
01830 reset_keyframe(1);
01831 }
01832
01833 void CWindowCanvas::reset_projector()
01834 {
01835 reset_keyframe(0);
01836 }
01837
01838 int CWindowCanvas::test_crop(int button_press, int &redraw)
01839 {
01840 int result = 0;
01841 int handle_selected = -1;
01842 float x1 = mwindow->edl->session->crop_x1;
01843 float y1 = mwindow->edl->session->crop_y1;
01844 float x2 = mwindow->edl->session->crop_x2;
01845 float y2 = mwindow->edl->session->crop_y2;
01846 float cursor_x = get_cursor_x();
01847 float cursor_y = get_cursor_y();
01848 float canvas_x1 = x1;
01849 float canvas_y1 = y1;
01850 float canvas_x2 = x2;
01851 float canvas_y2 = y2;
01852 float canvas_cursor_x = cursor_x;
01853 float canvas_cursor_y = cursor_y;
01854
01855 canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
01856
01857 output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1);
01858 output_to_canvas(mwindow->edl, 0, canvas_x2, canvas_y2);
01859
01860
01861 if(gui->current_operation == CWINDOW_CROP)
01862 {
01863 handle_selected = gui->crop_handle;
01864 }
01865 else
01866 if(canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W &&
01867 canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H)
01868 {
01869 handle_selected = 0;
01870 gui->crop_origin_x = x1;
01871 gui->crop_origin_y = y1;
01872 }
01873 else
01874 if(canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 &&
01875 canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H)
01876 {
01877 handle_selected = 1;
01878 gui->crop_origin_x = x2;
01879 gui->crop_origin_y = y1;
01880 }
01881 else
01882 if(canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W &&
01883 canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2)
01884 {
01885 handle_selected = 2;
01886 gui->crop_origin_x = x1;
01887 gui->crop_origin_y = y2;
01888 }
01889 else
01890 if(canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 &&
01891 canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2)
01892 {
01893 handle_selected = 3;
01894 gui->crop_origin_x = x2;
01895 gui->crop_origin_y = y2;
01896 }
01897 else
01898
01899 {
01900 gui->crop_origin_x = cursor_x;
01901 gui->crop_origin_y = cursor_y;
01902 }
01903
01904
01905
01906
01907
01908
01909 if(button_press)
01910 {
01911 if(gui->alt_down())
01912 {
01913 gui->crop_translate = 1;
01914 gui->crop_origin_x1 = x1;
01915 gui->crop_origin_y1 = y1;
01916 gui->crop_origin_x2 = x2;
01917 gui->crop_origin_y2 = y2;
01918 }
01919 else
01920 gui->crop_translate = 0;
01921
01922 gui->current_operation = CWINDOW_CROP;
01923 gui->crop_handle = handle_selected;
01924 gui->x_origin = cursor_x;
01925 gui->y_origin = cursor_y;
01926 result = 1;
01927
01928 if(handle_selected < 0 && !gui->crop_translate)
01929 {
01930 x2 = x1 = cursor_x;
01931 y2 = y1 = cursor_y;
01932 mwindow->edl->session->crop_x1 = (int)x1;
01933 mwindow->edl->session->crop_y1 = (int)y1;
01934 mwindow->edl->session->crop_x2 = (int)x2;
01935 mwindow->edl->session->crop_y2 = (int)y2;
01936 redraw = 1;
01937 }
01938 }
01939 else
01940
01941 if(gui->current_operation == CWINDOW_CROP && gui->crop_translate)
01942 {
01943 x1 = cursor_x - gui->x_origin + gui->crop_origin_x1;
01944 y1 = cursor_y - gui->y_origin + gui->crop_origin_y1;
01945 x2 = cursor_x - gui->x_origin + gui->crop_origin_x2;
01946 y2 = cursor_y - gui->y_origin + gui->crop_origin_y2;
01947
01948 mwindow->edl->session->crop_x1 = (int)x1;
01949 mwindow->edl->session->crop_y1 = (int)y1;
01950 mwindow->edl->session->crop_x2 = (int)x2;
01951 mwindow->edl->session->crop_y2 = (int)y2;
01952 result = 1;
01953 redraw = 1;
01954 }
01955 else
01956
01957 if(gui->current_operation == CWINDOW_CROP)
01958 {
01959 switch(gui->crop_handle)
01960 {
01961 case -1:
01962 x1 = gui->crop_origin_x;
01963 y1 = gui->crop_origin_y;
01964 x2 = gui->crop_origin_x;
01965 y2 = gui->crop_origin_y;
01966 if(cursor_x < gui->x_origin)
01967 {
01968 if(cursor_y < gui->y_origin)
01969 {
01970 x1 = cursor_x;
01971 y1 = cursor_y;
01972 }
01973 else
01974 if(cursor_y >= gui->y_origin)
01975 {
01976 x1 = cursor_x;
01977 y2 = cursor_y;
01978 }
01979 }
01980 else
01981 if(cursor_x >= gui->x_origin)
01982 {
01983 if(cursor_y < gui->y_origin)
01984 {
01985 y1 = cursor_y;
01986 x2 = cursor_x;
01987 }
01988 else
01989 if(cursor_y >= gui->y_origin)
01990 {
01991 x2 = cursor_x;
01992 y2 = cursor_y;
01993 }
01994 }
01995
01996
01997
01998
01999
02000
02001 break;
02002 case 0:
02003 x1 = cursor_x - gui->x_origin + gui->crop_origin_x;
02004 y1 = cursor_y - gui->y_origin + gui->crop_origin_y;
02005 break;
02006 case 1:
02007 x2 = cursor_x - gui->x_origin + gui->crop_origin_x;
02008 y1 = cursor_y - gui->y_origin + gui->crop_origin_y;
02009 break;
02010 case 2:
02011 x1 = cursor_x - gui->x_origin + gui->crop_origin_x;
02012 y2 = cursor_y - gui->y_origin + gui->crop_origin_y;
02013 break;
02014 case 3:
02015 x2 = cursor_x - gui->x_origin + gui->crop_origin_x;
02016 y2 = cursor_y - gui->y_origin + gui->crop_origin_y;
02017 break;
02018 }
02019
02020 if(!EQUIV(mwindow->edl->session->crop_x1, x1) ||
02021 !EQUIV(mwindow->edl->session->crop_x2, x2) ||
02022 !EQUIV(mwindow->edl->session->crop_y1, y1) ||
02023 !EQUIV(mwindow->edl->session->crop_y2, y2))
02024 {
02025 if (x1 > x2)
02026 {
02027 float tmp = x1;
02028 x1 = x2;
02029 x2 = tmp;
02030 switch (gui->crop_handle)
02031 {
02032 case 0: gui->crop_handle = 1; break;
02033 case 1: gui->crop_handle = 0; break;
02034 case 2: gui->crop_handle = 3; break;
02035 case 3: gui->crop_handle = 2; break;
02036 default: break;
02037 }
02038
02039 }
02040 if (y1 > y2)
02041 {
02042 float tmp = y1;
02043 y1 = y2;
02044 y2 = tmp;
02045 switch (gui->crop_handle)
02046 {
02047 case 0: gui->crop_handle = 2; break;
02048 case 1: gui->crop_handle = 3; break;
02049 case 2: gui->crop_handle = 0; break;
02050 case 3: gui->crop_handle = 1; break;
02051 default: break;
02052 }
02053 }
02054
02055 mwindow->edl->session->crop_x1 = (int)x1;
02056 mwindow->edl->session->crop_y1 = (int)y1;
02057 mwindow->edl->session->crop_x2 = (int)x2;
02058 mwindow->edl->session->crop_y2 = (int)y2;
02059 result = 1;
02060 redraw = 1;
02061 }
02062 }
02063 else
02064
02065 if(handle_selected >= 0)
02066 {
02067 switch(handle_selected)
02068 {
02069 case 0:
02070 set_cursor(UPLEFT_RESIZE);
02071 break;
02072 case 1:
02073 set_cursor(UPRIGHT_RESIZE);
02074 break;
02075 case 2:
02076 set_cursor(DOWNLEFT_RESIZE);
02077 break;
02078 case 3:
02079 set_cursor(DOWNRIGHT_RESIZE);
02080 break;
02081 }
02082 result = 1;
02083 }
02084 else
02085 {
02086 set_cursor(ARROW_CURSOR);
02087 }
02088 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
02089
02090 if(redraw)
02091 {
02092 CLAMP(mwindow->edl->session->crop_x1, 0, mwindow->edl->session->output_w);
02093 CLAMP(mwindow->edl->session->crop_x2, 0, mwindow->edl->session->output_w);
02094 CLAMP(mwindow->edl->session->crop_y1, 0, mwindow->edl->session->output_h);
02095 CLAMP(mwindow->edl->session->crop_y2, 0, mwindow->edl->session->output_h);
02096
02097
02098
02099
02100
02101 }
02102 return result;
02103 }
02104
02105
02106 void CWindowCanvas::draw_crop()
02107 {
02108 get_canvas()->set_inverse();
02109 get_canvas()->set_color(WHITE);
02110
02111 float x1 = mwindow->edl->session->crop_x1;
02112 float y1 = mwindow->edl->session->crop_y1;
02113 float x2 = mwindow->edl->session->crop_x2;
02114 float y2 = mwindow->edl->session->crop_y2;
02115
02116 output_to_canvas(mwindow->edl, 0, x1, y1);
02117 output_to_canvas(mwindow->edl, 0, x2, y2);
02118
02119 if(x2 - x1 && y2 - y1)
02120 get_canvas()->draw_rectangle((int)x1,
02121 (int)y1,
02122 (int)(x2 - x1),
02123 (int)(y2 - y1));
02124
02125 draw_crophandle((int)x1, (int)y1);
02126 draw_crophandle((int)x2 - CROPHANDLE_W, (int)y1);
02127 draw_crophandle((int)x1, (int)y2 - CROPHANDLE_H);
02128 draw_crophandle((int)x2 - CROPHANDLE_W, (int)y2 - CROPHANDLE_H);
02129 get_canvas()->set_opaque();
02130 }
02131
02132
02133
02134
02135
02136
02137
02138
02139 void CWindowCanvas::draw_bezier(int do_camera)
02140 {
02141 Track *track = gui->cwindow->calculate_affected_track();
02142
02143 if(!track) return;
02144
02145 float center_x;
02146 float center_y;
02147 float center_z;
02148 int64_t position = track->to_units(
02149 mwindow->edl->local_session->get_selectionstart(1),
02150 0);
02151
02152 track->automation->get_projector(¢er_x,
02153 ¢er_y,
02154 ¢er_z,
02155 position,
02156 PLAY_FORWARD);
02157
02158
02159
02160 center_x += mwindow->edl->session->output_w / 2;
02161 center_y += mwindow->edl->session->output_h / 2;
02162 float track_x1 = center_x - track->track_w / 2 * center_z;
02163 float track_y1 = center_y - track->track_h / 2 * center_z;
02164 float track_x2 = track_x1 + track->track_w * center_z;
02165 float track_y2 = track_y1 + track->track_h * center_z;
02166
02167 output_to_canvas(mwindow->edl, 0, track_x1, track_y1);
02168 output_to_canvas(mwindow->edl, 0, track_x2, track_y2);
02169
02170 #define DRAW_PROJECTION(offset) \
02171 get_canvas()->draw_rectangle((int)track_x1 + offset, \
02172 (int)track_y1 + offset, \
02173 (int)(track_x2 - track_x1), \
02174 (int)(track_y2 - track_y1)); \
02175 get_canvas()->draw_line((int)track_x1 + offset, \
02176 (int)track_y1 + offset, \
02177 (int)track_x2 + offset, \
02178 (int)track_y2 + offset); \
02179 get_canvas()->draw_line((int)track_x2 + offset, \
02180 (int)track_y1 + offset, \
02181 (int)track_x1 + offset, \
02182 (int)track_y2 + offset); \
02183
02184
02185
02186 get_canvas()->set_color(BLACK);
02187 DRAW_PROJECTION(1);
02188
02189
02190 if(do_camera)
02191 get_canvas()->set_color(GREEN);
02192 else
02193 get_canvas()->set_color(RED);
02194
02195 DRAW_PROJECTION(0);
02196
02197
02198 }
02199
02200
02201
02202 int CWindowCanvas::test_bezier(int button_press,
02203 int &redraw,
02204 int &redraw_canvas,
02205 int &rerender,
02206 int do_camera)
02207 {
02208 int result = 0;
02209
02210
02211
02212 if(!button_press)
02213 {
02214
02215 float cursor_x = get_cursor_x();
02216 float cursor_y = get_cursor_y();
02217 canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
02218
02219 if(gui->current_operation == CWINDOW_CAMERA ||
02220 gui->current_operation == CWINDOW_PROJECTOR)
02221 {
02222 if(!gui->ctrl_down() && gui->shift_down() && !gui->translating_zoom)
02223 {
02224 gui->translating_zoom = 1;
02225 gui->reset_affected();
02226 }
02227 else
02228 if(!gui->ctrl_down() && !gui->shift_down() && gui->translating_zoom)
02229 {
02230 gui->translating_zoom = 0;
02231 gui->reset_affected();
02232 }
02233
02234
02235 float last_center_x;
02236 float last_center_y;
02237 float last_center_z;
02238 int created;
02239
02240 if(!gui->affected_x && !gui->affected_y && !gui->affected_z)
02241 {
02242 FloatAutos *affected_x_autos;
02243 FloatAutos *affected_y_autos;
02244 FloatAutos *affected_z_autos;
02245 if(!gui->affected_track) return 0;
02246 double position = mwindow->edl->local_session->get_selectionstart(1);
02247 int64_t track_position = gui->affected_track->to_units(position, 0);
02248
02249 if(mwindow->edl->session->cwindow_operation == CWINDOW_CAMERA)
02250 {
02251 affected_x_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_X];
02252 affected_y_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_Y];
02253 affected_z_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_Z];
02254 }
02255 else
02256 {
02257 affected_x_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_X];
02258 affected_y_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_Y];
02259 affected_z_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_Z];
02260 }
02261
02262
02263 if(gui->translating_zoom)
02264 {
02265 FloatAuto *previous = 0;
02266 FloatAuto *next = 0;
02267 float new_z = affected_z_autos->get_value(
02268 track_position,
02269 PLAY_FORWARD,
02270 previous,
02271 next);
02272 gui->affected_z =
02273 (FloatAuto*)gui->cwindow->calculate_affected_auto(
02274 affected_z_autos, 1, &created, 0);
02275 if(created)
02276 {
02277 gui->affected_z->value = new_z;
02278 gui->affected_z->control_in_value = 0;
02279 gui->affected_z->control_out_value = 0;
02280 gui->affected_z->control_in_position = 0;
02281 gui->affected_z->control_out_position = 0;
02282 redraw_canvas = 1;
02283 }
02284 }
02285 else
02286 {
02287 FloatAuto *previous = 0;
02288 FloatAuto *next = 0;
02289 float new_x = affected_x_autos->get_value(
02290 track_position,
02291 PLAY_FORWARD,
02292 previous,
02293 next);
02294 previous = 0;
02295 next = 0;
02296 float new_y = affected_y_autos->get_value(
02297 track_position,
02298 PLAY_FORWARD,
02299 previous,
02300 next);
02301 gui->affected_x =
02302 (FloatAuto*)gui->cwindow->calculate_affected_auto(
02303 affected_x_autos, 1, &created, 0);
02304 if(created)
02305 {
02306 gui->affected_x->value = new_x;
02307 gui->affected_x->control_in_value = 0;
02308 gui->affected_x->control_out_value = 0;
02309 gui->affected_x->control_in_position = 0;
02310 gui->affected_x->control_out_position = 0;
02311 redraw_canvas = 1;
02312 }
02313 gui->affected_y =
02314 (FloatAuto*)gui->cwindow->calculate_affected_auto(
02315 affected_y_autos, 1, &created, 0);
02316 if(created)
02317 {
02318 gui->affected_y->value = new_y;
02319 gui->affected_y->control_in_value = 0;
02320 gui->affected_y->control_out_value = 0;
02321 gui->affected_y->control_in_position = 0;
02322 gui->affected_y->control_out_position = 0;
02323 redraw_canvas = 1;
02324 }
02325 }
02326
02327 calculate_origin();
02328
02329 if(gui->translating_zoom)
02330 {
02331 gui->center_z = gui->affected_z->value;
02332 }
02333 else
02334 {
02335 gui->center_x = gui->affected_x->value;
02336 gui->center_y = gui->affected_y->value;
02337 }
02338
02339 rerender = 1;
02340 redraw = 1;
02341 }
02342
02343
02344 if(gui->translating_zoom)
02345 {
02346 last_center_z = gui->affected_z->value;
02347 }
02348 else
02349 {
02350 last_center_x = gui->affected_x->value;
02351 last_center_y = gui->affected_y->value;
02352 }
02353
02354 if(gui->translating_zoom)
02355 {
02356 gui->affected_z->value = gui->center_z +
02357 (cursor_y - gui->y_origin) / 128;
02358
02359 if(gui->affected_z->value < 0) gui->affected_z->value = 0;
02360 if(!EQUIV(last_center_z, gui->affected_z->value))
02361 {
02362 rerender = 1;
02363 redraw = 1;
02364 redraw_canvas = 1;
02365 }
02366 }
02367 else
02368 {
02369 gui->affected_x->value = gui->center_x + cursor_x - gui->x_origin;
02370 gui->affected_y->value = gui->center_y + cursor_y - gui->y_origin;
02371 if(!EQUIV(last_center_x, gui->affected_x->value) ||
02372 !EQUIV(last_center_y, gui->affected_y->value))
02373 {
02374 rerender = 1;
02375 redraw = 1;
02376 redraw_canvas = 1;
02377 }
02378 }
02379 }
02380
02381 result = 1;
02382 }
02383 else
02384
02385 {
02386
02387
02388
02389 gui->affected_track = gui->cwindow->calculate_affected_track();
02390 gui->reset_affected();
02391
02392 if(gui->affected_track)
02393 {
02394 gui->current_operation =
02395 mwindow->edl->session->cwindow_operation;
02396 result = 1;
02397 }
02398 }
02399
02400 return result;
02401 }
02402
02403 int CWindowCanvas::test_zoom(int &redraw)
02404 {
02405 int result = 0;
02406 float zoom = get_zoom();
02407 float x;
02408 float y;
02409
02410 if(!mwindow->edl->session->cwindow_scrollbars)
02411 {
02412 mwindow->edl->session->cwindow_scrollbars = 1;
02413 zoom = 1.0;
02414 x = mwindow->edl->session->output_w / 2;
02415 y = mwindow->edl->session->output_h / 2;
02416 }
02417 else
02418 {
02419 x = get_cursor_x();
02420 y = get_cursor_y();
02421 canvas_to_output(mwindow->edl,
02422 0,
02423 x,
02424 y);
02425
02426
02427
02428
02429 int current_index = 0;
02430 for(current_index = 0 ; current_index < total_zooms; current_index++)
02431 if(EQUIV(my_zoom_table[current_index], zoom)) break;
02432
02433
02434
02435 if(get_buttonpress() == 5 ||
02436 gui->ctrl_down() ||
02437 gui->shift_down())
02438 {
02439 current_index--;
02440 }
02441 else
02442
02443 {
02444 current_index++;
02445 }
02446 CLAMP(current_index, 0, total_zooms - 1);
02447 zoom = my_zoom_table[current_index];
02448 }
02449
02450 x = x - w / zoom / 2;
02451 y = y - h / zoom / 2;
02452
02453
02454 int x_i = (int)x;
02455 int y_i = (int)y;
02456
02457
02458
02459
02460 update_zoom(x_i,
02461 y_i,
02462 zoom);
02463 reposition_window(mwindow->edl,
02464 mwindow->theme->ccanvas_x,
02465 mwindow->theme->ccanvas_y,
02466 mwindow->theme->ccanvas_w,
02467 mwindow->theme->ccanvas_h);
02468 redraw = 1;
02469 result = 1;
02470
02471
02472 gui->zoom_panel->update(zoom);
02473
02474 return result;
02475 }
02476
02477
02478 void CWindowCanvas::calculate_origin()
02479 {
02480 gui->x_origin = get_cursor_x();
02481 gui->y_origin = get_cursor_y();
02482
02483 canvas_to_output(mwindow->edl, 0, gui->x_origin, gui->y_origin);
02484
02485 }
02486
02487
02488 int CWindowCanvas::cursor_leave_event()
02489 {
02490 set_cursor(ARROW_CURSOR);
02491 return 1;
02492 }
02493
02494 int CWindowCanvas::cursor_enter_event()
02495 {
02496 int redraw = 0;
02497 switch(mwindow->edl->session->cwindow_operation)
02498 {
02499 case CWINDOW_CAMERA:
02500 case CWINDOW_PROJECTOR:
02501 set_cursor(MOVE_CURSOR);
02502 break;
02503 case CWINDOW_ZOOM:
02504 set_cursor(MOVE_CURSOR);
02505 break;
02506 case CWINDOW_CROP:
02507 test_crop(0, redraw);
02508 break;
02509 case CWINDOW_PROTECT:
02510 set_cursor(ARROW_CURSOR);
02511 break;
02512 case CWINDOW_MASK:
02513 set_cursor(CROSS_CURSOR);
02514 break;
02515 case CWINDOW_EYEDROP:
02516 set_cursor(CROSS_CURSOR);
02517 break;
02518 }
02519 return 1;
02520 }
02521
02522 int CWindowCanvas::cursor_motion_event()
02523 {
02524 int redraw = 0, result = 0, rerender = 0, redraw_canvas = 0;
02525
02526
02527 switch(gui->current_operation)
02528 {
02529 case CWINDOW_SCROLL:
02530 {
02531 float zoom = get_zoom();
02532 float cursor_x = get_cursor_x();
02533 float cursor_y = get_cursor_y();
02534
02535 float zoom_x, zoom_y, conformed_w, conformed_h;
02536 get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
02537 cursor_x = (float)cursor_x / zoom_x + gui->x_offset;
02538 cursor_y = (float)cursor_y / zoom_y + gui->y_offset;
02539
02540
02541
02542 int x = (int)(gui->x_origin - cursor_x + gui->x_offset);
02543 int y = (int)(gui->y_origin - cursor_y + gui->y_offset);
02544
02545 update_zoom(x,
02546 y,
02547 zoom);
02548 update_scrollbars();
02549 redraw = 1;
02550 result = 1;
02551 break;
02552 }
02553
02554 case CWINDOW_CAMERA:
02555 result = test_bezier(0, redraw, redraw_canvas, rerender, 1);
02556 break;
02557
02558 case CWINDOW_PROJECTOR:
02559 result = test_bezier(0, redraw, redraw_canvas, rerender, 0);
02560 break;
02561
02562
02563 case CWINDOW_CROP:
02564
02565 result = test_crop(0, redraw);
02566 break;
02567
02568 case CWINDOW_MASK:
02569 case CWINDOW_MASK_CONTROL_IN:
02570 case CWINDOW_MASK_CONTROL_OUT:
02571 case CWINDOW_MASK_TRANSLATE:
02572 result = do_mask(redraw,
02573 rerender,
02574 0,
02575 1,
02576 0);
02577 break;
02578
02579 case CWINDOW_EYEDROP:
02580 result = do_eyedrop(rerender, 0);
02581 break;
02582
02583 }
02584
02585
02586
02587 if(!result)
02588 {
02589 switch(mwindow->edl->session->cwindow_operation)
02590 {
02591 case CWINDOW_CROP:
02592 result = test_crop(0, redraw);
02593 break;
02594 }
02595 }
02596
02597
02598
02599
02600
02601
02602 if(redraw)
02603 {
02604 draw_refresh();
02605 gui->update_tool();
02606 }
02607
02608 if(redraw_canvas)
02609 {
02610 mwindow->gui->lock_window("CWindowCanvas::cursor_motion_event 1");
02611 mwindow->gui->canvas->draw_overlays();
02612 mwindow->gui->canvas->flash();
02613 mwindow->gui->unlock_window();
02614 }
02615
02616 if(rerender)
02617 {
02618 mwindow->restart_brender();
02619 mwindow->sync_parameters(CHANGE_PARAMS);
02620 gui->cwindow->playback_engine->que->send_command(CURRENT_FRAME,
02621 CHANGE_NONE,
02622 mwindow->edl,
02623 1);
02624 if(!redraw) gui->update_tool();
02625 }
02626 return result;
02627 }
02628
02629 int CWindowCanvas::button_press_event()
02630 {
02631 int result = 0;
02632 int redraw = 0;
02633 int redraw_canvas = 0;
02634 int rerender = 0;
02635
02636 if(Canvas::button_press_event()) return 1;
02637
02638 gui->translating_zoom = gui->shift_down();
02639
02640 calculate_origin();
02641
02642
02643 float zoom_x, zoom_y, conformed_w, conformed_h;
02644 get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
02645 gui->x_offset = get_x_offset(mwindow->edl, 0, zoom_x, conformed_w, conformed_h);
02646 gui->y_offset = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h);
02647
02648
02649 if(get_buttonpress() == 2)
02650 {
02651 gui->current_operation = CWINDOW_SCROLL;
02652 result = 1;
02653 }
02654 else
02655
02656 {
02657 switch(mwindow->edl->session->cwindow_operation)
02658 {
02659 case CWINDOW_CAMERA:
02660 result = test_bezier(1, redraw, redraw_canvas, rerender, 1);
02661 break;
02662
02663 case CWINDOW_PROJECTOR:
02664 result = test_bezier(1, redraw, redraw_canvas, rerender, 0);
02665 break;
02666
02667 case CWINDOW_ZOOM:
02668 result = test_zoom(redraw);
02669 break;
02670
02671 case CWINDOW_CROP:
02672 result = test_crop(1, redraw);
02673 break;
02674
02675 case CWINDOW_MASK:
02676 if(get_buttonpress() == 1)
02677 result = do_mask(redraw, rerender, 1, 0, 0);
02678 break;
02679
02680 case CWINDOW_EYEDROP:
02681 result = do_eyedrop(rerender, 1);
02682 break;
02683 }
02684 }
02685
02686 if(redraw)
02687 {
02688 draw_refresh();
02689 gui->update_tool();
02690 }
02691
02692
02693 if(rerender)
02694 {
02695 mwindow->restart_brender();
02696 mwindow->sync_parameters(CHANGE_PARAMS);
02697 gui->cwindow->playback_engine->que->send_command(CURRENT_FRAME,
02698 CHANGE_NONE,
02699 mwindow->edl,
02700 1);
02701 if(!redraw) gui->update_tool();
02702 }
02703 return result;
02704 }
02705
02706 int CWindowCanvas::button_release_event()
02707 {
02708 int result = 0;
02709
02710 switch(gui->current_operation)
02711 {
02712 case CWINDOW_SCROLL:
02713 result = 1;
02714 break;
02715
02716 case CWINDOW_CAMERA:
02717 mwindow->undo->update_undo(_("camera"), LOAD_AUTOMATION);
02718 break;
02719
02720 case CWINDOW_PROJECTOR:
02721 mwindow->undo->update_undo(_("projector"), LOAD_AUTOMATION);
02722 break;
02723
02724 case CWINDOW_MASK:
02725 case CWINDOW_MASK_CONTROL_IN:
02726 case CWINDOW_MASK_CONTROL_OUT:
02727 case CWINDOW_MASK_TRANSLATE:
02728 mwindow->undo->update_undo(_("mask point"), LOAD_AUTOMATION);
02729 break;
02730
02731 }
02732
02733 gui->current_operation = CWINDOW_NONE;
02734 return result;
02735 }
02736
02737 void CWindowCanvas::zoom_resize_window(float percentage)
02738 {
02739 int canvas_w, canvas_h;
02740 calculate_sizes(mwindow->edl->get_aspect_ratio(),
02741 mwindow->edl->session->output_w,
02742 mwindow->edl->session->output_h,
02743 percentage,
02744 canvas_w,
02745 canvas_h);
02746 int new_w, new_h;
02747 new_w = canvas_w + (gui->get_w() - mwindow->theme->ccanvas_w);
02748 new_h = canvas_h + (gui->get_h() - mwindow->theme->ccanvas_h);
02749 gui->resize_window(new_w, new_h);
02750 gui->resize_event(new_w, new_h);
02751 }
02752
02753 void CWindowCanvas::toggle_controls()
02754 {
02755 mwindow->session->cwindow_controls = !mwindow->session->cwindow_controls;
02756 gui->resize_event(gui->get_w(), gui->get_h());
02757 }
02758
02759 int CWindowCanvas::get_cwindow_controls()
02760 {
02761 return mwindow->session->cwindow_controls;
02762 }
02763
02764
02765