Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

cwindowgui.C

Go to the documentation of this file.
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 // Meters required by composite panel
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 //      add_subwindow(clock = new MainClock(mwindow, 
00172 //              mwindow->theme->ctime_x, 
00173 //              mwindow->theme->ctime_y));
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 //      destination = new CWindowDestination(mwindow, 
00184 //              this, 
00185 //              mwindow->theme->cdest_x,
00186 //              mwindow->theme->cdest_y);
00187 //      destination->create_objects();
00188 
00189 // Must create after meter panel
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 // Recalibrate pointer motion range
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 //      clock->reposition_window(mwindow->theme->ctime_x, 
00246 //              mwindow->theme->ctime_y);
00247 
00248         zoom_panel->reposition_window(mwindow->theme->czoom_x, 
00249                 mwindow->theme->czoom_y);
00250 
00251 //      destination->reposition_window(mwindow->theme->cdest_x,
00252 //              mwindow->theme->cdest_y);
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 // TODO
00286 // Don't refresh the canvas in a load file operation which is going to
00287 // refresh it anyway.
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 //      if(mwindow->edl->session->cwindow_scrollbars)
00349 //      {
00350                 zoom_panel->zoom_tumbler->handle_up_event();
00351 //      }
00352 //      else
00353 //      {
00354 //      }
00355 }
00356 
00357 void CWindowGUI::keyboard_zoomout()
00358 {
00359 //      if(mwindow->edl->session->cwindow_scrollbars)
00360 //      {
00361                 zoom_panel->zoom_tumbler->handle_down_event();
00362 //      }
00363 //      else
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 // Hide highlighting
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 //printf("CWindowGUI::drag_stop 1\n");
00453                 Track *affected_track = cwindow->calculate_affected_track();
00454 //printf("CWindowGUI::drag_stop 2\n");
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 // CWindowDestination::CWindowDestination(MWindow *mwindow, CWindowGUI *cwindow, int x, int y)
00665 //  : BC_PopupTextBox(cwindow, 
00666 //      &cwindow->destinations, 
00667 //      cwindow->destinations.values[cwindow->cwindow->destination]->get_text(),
00668 //      x, 
00669 //      y, 
00670 //      70, 
00671 //      200)
00672 // {
00673 //      this->mwindow = mwindow;
00674 //      this->cwindow = cwindow;
00675 // }
00676 // 
00677 // CWindowDestination::~CWindowDestination()
00678 // {
00679 // }
00680 // 
00681 // int CWindowDestination::handle_event()
00682 // {
00683 //      return 1;
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 //printf("CWindowCanvas::draw_refresh 1 %f\n", mwindow->edl->session->cwindow_zoom);
00780                 canvas->clear_box(0, 0, canvas->get_w(), canvas->get_h());
00781 //printf("CWindowCanvas::draw_refresh 2\n");
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 //printf("CWindowCanvas::draw_refresh 3 %d\n", refresh_frame->get_color_model());
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 // printf("CWindowCanvas::draw_refresh %d %d %d %d -> %d %d %d %d\n", 
00799 // in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h);
00800 //canvas->clear_box(0, 0, canvas->get_w(), canvas->get_h());
00801 
00802 
00803 //printf("CWindowCanvas::draw_refresh 5\n");
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 //printf("CWindowCanvas::draw_refresh 6\n");
00816                 }
00817                 else
00818                 {
00819 //printf("CWindowCanvas::draw_refresh 7\n");
00820                         canvas->clear_box(0, 0, canvas->get_w(), canvas->get_h());
00821 //printf("CWindowCanvas::draw_refresh 8\n");
00822                 }
00823 
00824 //printf("CWindowCanvas::draw_refresh 9\n");
00825                 draw_overlays();
00826                 canvas->flash();
00827                 canvas->flush();
00828 //printf("CWindowCanvas::draw_refresh 10\n");
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 // Retrieve points from top recordable track
00857 //printf("CWindowCanvas::do_mask 1\n");
00858         Track *track = gui->cwindow->calculate_affected_track();
00859 //printf("CWindowCanvas::do_mask 2\n");
00860 
00861         if(!track) return 0;
00862 //printf("CWindowCanvas::do_mask 3\n");
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 //printf("CWindowCanvas::do_mask 4\n");
00873 
00874 // Projector zooms relative to the center of the track output.
00875         float half_track_w = (float)track->track_w / 2;
00876         float half_track_h = (float)track->track_h / 2;
00877 // Translate mask to projection
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 // Get position of cursor relative to mask
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 // Fix cursor origin
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 // Points of closest line
00908         int shortest_point1 = -1;
00909         int shortest_point2 = -1;
00910 // Closest point
00911         int shortest_point = -1;
00912 // Distance to closest line
00913         float shortest_line_distance = BC_INFINITY;
00914 // Distance to closest point
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 //printf("CWindowCanvas::do_mask 1 %d\n", points.total);
00930 
00931 // Never draw closed polygon and a closed
00932 // polygon is harder to add points to.
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 //printf("CWindowCanvas::do_mask 1 %f, %f -> %f, %f projectorz=%f\n",
00945 //point1->x, point1->y, point2->x, point2->y, projector_z);
00946                         for(int j = 0; j <= segments && !result; j++)
00947                         {
00948 //printf("CWindowCanvas::do_mask 1 %f, %f -> %f, %f\n", x0, y0, x3, y3);
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 // Test new point addition
00979                                 if(button_press)
00980                                 {
00981                                         float line_distance = 
00982                                                 sqrt(SQR(x - mask_cursor_x) + SQR(y - mask_cursor_y));
00983 
00984 //printf("CWindowCanvas::do_mask 1 x=%f mask_cursor_x=%f y=%f mask_cursor_y=%f %f %f %d, %d\n", 
00985 //x, mask_cursor_x, y, mask_cursor_y, line_distance, shortest_line_distance, shortest_point1, shortest_point2);
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 //printf("CWindowCanvas::do_mask 2 %f %f %d, %d\n", line_distance, shortest_line_distance, shortest_point1, shortest_point2);
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 // Test existing point selection
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 // Test first point
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 // Test second point
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 //printf("CWindowCanvas::do_mask %d %f %f\n", i, distance, selected_control_point_distance);
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 // Draw joining line
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 // Draw second anchor
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