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