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