rework undo compression, add shift viewer overwr/copy/clip/splice, fix paste edl...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / vwindowgui.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "arender.h"
23 #include "asset.h"
24 #include "assets.h"
25 #include "awindowgui.h"
26 #include "awindow.h"
27 #include "cache.h"
28 #include "canvas.h"
29 #include "clip.h"
30 #include "clipedit.h"
31 #include "edl.h"
32 #include "edlsession.h"
33 #include "filesystem.h"
34 #include "filexml.h"
35 #include "fonts.h"
36 #include "keys.h"
37 #include "labels.h"
38 #include "language.h"
39 #include "localsession.h"
40 #include "mainclock.h"
41 #include "mainmenu.h"
42 #include "mainsession.h"
43 #include "mainundo.h"
44 #include "meterpanel.h"
45 #include "mwindowgui.h"
46 #include "mwindow.h"
47 #include "playtransport.h"
48 #include "preferences.h"
49 #include "renderengine.h"
50 #include "samples.h"
51 #include "theme.h"
52 #include "timebar.h"
53 #include "tracks.h"
54 #include "transportque.h"
55 #include "vframe.h"
56 #include "vplayback.h"
57 #include "vtimebar.h"
58 #include "vwindowgui.h"
59 #include "vwindow.h"
60
61
62
63
64 VWindowGUI::VWindowGUI(MWindow *mwindow, VWindow *vwindow)
65  : BC_Window(_(PROGRAM_NAME ": Viewer"),
66         mwindow->session->vwindow_x,
67         mwindow->session->vwindow_y,
68         mwindow->session->vwindow_w,
69         mwindow->session->vwindow_h,
70         100,
71         100,
72         1,
73         1,
74         0) // Hide it
75 {
76         this->mwindow = mwindow;
77         this->vwindow = vwindow;
78         canvas = 0;
79         transport = 0;
80         edit_panel = 0;
81         meters = 0;
82 //      source = 0;
83         strcpy(loaded_title, "");
84         highlighted = 0;
85 }
86
87 VWindowGUI::~VWindowGUI()
88 {
89         vwindow->playback_engine->interrupt_playback(1);
90         sources.remove_all_objects();
91         labels.remove_all_objects();
92         delete canvas;
93         delete transport;
94         delete edit_panel;
95         delete meters;
96 //      delete source;
97 }
98
99 void VWindowGUI::draw_wave()
100 {
101         TransportCommand command;
102         command.command = NORMAL_FWD;
103         command.get_edl()->copy_all(vwindow->get_edl());
104         command.change_type = CHANGE_ALL;
105         command.realtime = 0;
106         RenderEngine *render_engine = new RenderEngine(0, mwindow->preferences, 0, 0);
107         CICache *cache = new CICache(mwindow->preferences);
108         render_engine->set_acache(cache);
109         render_engine->arm_command(&command);
110
111         double duration = 1.;
112         int w = mwindow->edl->session->output_w;
113         int h = mwindow->edl->session->output_h;
114         VFrame *vframe = new VFrame(w, h, BC_RGB888);
115         int sample_rate = mwindow->edl->get_sample_rate();
116         int channels = mwindow->edl->session->audio_channels;
117         if( channels > 2 ) channels = 2;
118         int64_t bfrsz = sample_rate * duration;
119         Samples *samples[MAXCHANNELS];
120         int ch = 0;
121         while( ch < channels ) samples[ch++] = new Samples(bfrsz);
122         while( ch < MAXCHANNELS ) samples[ch++] = 0;
123         render_engine->arender->process_buffer(samples, bfrsz, 0);
124
125         static int line_colors[2] = { GREEN, YELLOW };
126         static int base_colors[2] = { RED, PINK };
127         for( int i=channels; --i>=0; ) {
128                 AssetPicon::draw_wave(vframe, samples[i]->get_data(), bfrsz,
129                         base_colors[i], line_colors[i]);
130         }
131
132         for( int i=channels; --i>=0; ) delete samples[i];
133         delete render_engine;
134         delete cache;
135         delete canvas->refresh_frame;
136         canvas->refresh_frame = vframe;
137         canvas->draw_refresh(1);
138 }
139
140 void VWindowGUI::change_source(EDL *edl, const char *title)
141 {
142 //printf("VWindowGUI::change_source %d\n", __LINE__);
143
144         update_sources(title);
145         strcpy(loaded_title, title);
146         char string[BCTEXTLEN];
147         if(title[0])
148                 sprintf(string, _(PROGRAM_NAME ": %s"), title);
149         else
150                 sprintf(string, _(PROGRAM_NAME ": Viewer"));
151
152         lock_window("VWindowGUI::change_source");
153         canvas->clear();
154         if( edl &&
155             !edl->tracks->playable_video_tracks() &&
156             edl->tracks->playable_audio_tracks() )
157                 draw_wave();
158         timebar->update(0);
159         set_title(string);
160         unlock_window();
161 }
162
163
164 // Get source list from master EDL
165 void VWindowGUI::update_sources(const char *title)
166 {
167         lock_window("VWindowGUI::update_sources");
168         sources.remove_all_objects();
169
170         for( int i=0; i<mwindow->edl->clips.size(); ++i ) {
171                 char *clip_title = mwindow->edl->clips.values[i]->local_session->clip_title;
172                 int exists = 0;
173
174                 for( int j=0; !exists && j<sources.size(); ++j ) {
175                         if( !strcasecmp(sources.values[j]->get_text(), clip_title) )
176                                 exists = 1;
177                 }
178
179                 if( !exists )
180                         sources.append(new BC_ListBoxItem(clip_title));
181         }
182
183         FileSystem fs;
184         for( Asset *current=mwindow->edl->assets->first; current; current=NEXT ) {
185                 char clip_title[BCTEXTLEN];
186                 fs.extract_name(clip_title, current->path);
187                 int exists = 0;
188
189                 for( int j=0; !exists && j<sources.size(); ++j ) {
190                         if( !strcasecmp(sources.values[j]->get_text(), clip_title) )
191                                 exists = 1;
192                 }
193
194                 if( !exists )
195                         sources.append(new BC_ListBoxItem(clip_title));
196         }
197
198         unlock_window();
199 }
200
201 void VWindowGUI::create_objects()
202 {
203         in_point = 0;
204         out_point = 0;
205         lock_window("VWindowGUI::create_objects");
206         set_icon(mwindow->theme->get_image("vwindow_icon"));
207
208 //printf("VWindowGUI::create_objects 1\n");
209         mwindow->theme->get_vwindow_sizes(this);
210         mwindow->theme->draw_vwindow_bg(this);
211         flash(0);
212
213         meters = new VWindowMeters(mwindow,
214                 this,
215                 mwindow->theme->vmeter_x,
216                 mwindow->theme->vmeter_y,
217                 mwindow->theme->vmeter_h);
218         meters->create_objects();
219
220 //printf("VWindowGUI::create_objects 1\n");
221 // Requires meters to build
222         edit_panel = new VWindowEditing(mwindow, vwindow);
223         edit_panel->set_meters(meters);
224         edit_panel->create_objects();
225
226 //printf("VWindowGUI::create_objects 1\n");
227         transport = new VWindowTransport(mwindow,
228                 this,
229                 mwindow->theme->vtransport_x,
230                 mwindow->theme->vtransport_y);
231         transport->create_objects();
232
233 //printf("VWindowGUI::create_objects 1\n");
234 //      add_subwindow(fps_title = new BC_Title(mwindow->theme->vedit_x, y, ""));
235     add_subwindow(clock = new MainClock(mwindow,
236                 mwindow->theme->vtime_x,
237                 mwindow->theme->vtime_y,
238                 mwindow->theme->vtime_w));
239
240         canvas = new VWindowCanvas(mwindow, this);
241         canvas->create_objects(mwindow->edl);
242         canvas->use_vwindow();
243
244
245 //printf("VWindowGUI::create_objects 1\n");
246         add_subwindow(timebar = new VTimeBar(mwindow,
247                 this,
248                 mwindow->theme->vtimebar_x,
249                 mwindow->theme->vtimebar_y,
250                 mwindow->theme->vtimebar_w,
251                 mwindow->theme->vtimebar_h));
252         timebar->create_objects();
253 //printf("VWindowGUI::create_objects 2\n");
254
255
256 //printf("VWindowGUI::create_objects 1\n");
257 //      source = new VWindowSource(mwindow,
258 //              this,
259 //              mwindow->theme->vsource_x,
260 //              mwindow->theme->vsource_y);
261 //      source->create_objects();
262         update_sources(_("None"));
263
264 //printf("VWindowGUI::create_objects 2\n");
265         deactivate();
266
267         show_window();
268         unlock_window();
269 }
270
271 int VWindowGUI::resize_event(int w, int h)
272 {
273         mwindow->session->vwindow_x = get_x();
274         mwindow->session->vwindow_y = get_y();
275         mwindow->session->vwindow_w = w;
276         mwindow->session->vwindow_h = h;
277
278         mwindow->theme->get_vwindow_sizes(this);
279         mwindow->theme->draw_vwindow_bg(this);
280         flash(0);
281
282 //printf("VWindowGUI::resize_event %d %d\n", __LINE__, mwindow->theme->vedit_y);
283         edit_panel->reposition_buttons(mwindow->theme->vedit_x,
284                 mwindow->theme->vedit_y);
285
286         timebar->resize_event();
287         transport->reposition_buttons(mwindow->theme->vtransport_x,
288                 mwindow->theme->vtransport_y);
289         clock->reposition_window(mwindow->theme->vtime_x,
290                 mwindow->theme->vtime_y,
291                 mwindow->theme->vtime_w,
292                 clock->get_h());
293         canvas->reposition_window(0,
294                 mwindow->theme->vcanvas_x,
295                 mwindow->theme->vcanvas_y,
296                 mwindow->theme->vcanvas_w,
297                 mwindow->theme->vcanvas_h);
298 //printf("VWindowGUI::resize_event %d %d\n", __LINE__, mwindow->theme->vcanvas_x);
299 //      source->reposition_window(mwindow->theme->vsource_x,
300 //              mwindow->theme->vsource_y);
301         meters->reposition_window(mwindow->theme->vmeter_x,
302                 mwindow->theme->vmeter_y,
303                 -1,
304                 mwindow->theme->vmeter_h);
305
306         BC_WindowBase::resize_event(w, h);
307         return 1;
308 }
309
310
311
312
313
314 int VWindowGUI::translation_event()
315 {
316         mwindow->session->vwindow_x = get_x();
317         mwindow->session->vwindow_y = get_y();
318         return 0;
319 }
320
321 int VWindowGUI::close_event()
322 {
323         hide_window();
324         int i = mwindow->vwindows.size();
325         while( --i >= 0 && mwindow->vwindows.get(i)->gui != this );
326         if( i > 0 ) {
327                 set_done(0);
328                 return 1;
329         }
330
331         mwindow->session->show_vwindow = 0;
332         unlock_window();
333
334         mwindow->gui->lock_window("VWindowGUI::close_event");
335         mwindow->gui->mainmenu->show_vwindow->set_checked(0);
336         mwindow->gui->unlock_window();
337
338         lock_window("VWindowGUI::close_event");
339         mwindow->save_defaults();
340         return 1;
341 }
342
343 int VWindowGUI::keypress_event()
344 {
345         int result = 0;
346         switch(get_keypress())
347         {
348                 case 'w':
349                 case 'W':
350                         close_event();
351                         result = 1;
352                         break;
353                 case 'z':
354                         mwindow->undo_entry(this);
355                         break;
356                 case 'Z':
357                         mwindow->redo_entry(this);
358                         break;
359                 case 'f':
360                         unlock_window();
361                         if(mwindow->session->vwindow_fullscreen)
362                                 canvas->stop_fullscreen();
363                         else
364                                 canvas->start_fullscreen();
365                         lock_window("VWindowGUI::keypress_event 1");
366                         break;
367                 case ESC:
368                         unlock_window();
369                         if(mwindow->session->vwindow_fullscreen)
370                                 canvas->stop_fullscreen();
371                         lock_window("VWindowGUI::keypress_event 2");
372                         break;
373         }
374         if(!result) result = transport->keypress_event();
375         return result;
376 }
377
378 void VWindowGUI::stop_transport(const char *lock_msg)
379 {
380         if( !transport->is_stopped() ) {
381                 if( lock_msg ) unlock_window();
382                 transport->handle_transport(STOP, 1, 0, 0);
383                 if( lock_msg ) lock_window(lock_msg);
384         }
385 }
386
387 int VWindowGUI::button_press_event()
388 {
389         if( vwindow->get_edl() != 0 && canvas->get_canvas() &&
390             mwindow->edl->session->vwindow_click2play &&
391             canvas->get_canvas()->get_cursor_over_window() ) {
392                 switch( get_buttonpress() ) {
393                 case LEFT_BUTTON:
394                         if( !vwindow->playback_engine->is_playing_back ) {
395                                 double length = vwindow->get_edl()->tracks->total_playable_length();
396                                 double position = vwindow->playback_engine->get_tracking_position();
397                                 if( position >= length ) transport->goto_start();
398                         }
399                         return transport->forward_play->handle_event();
400                 case MIDDLE_BUTTON:
401                         if( !vwindow->playback_engine->is_playing_back ) {
402                                 double position = vwindow->playback_engine->get_tracking_position();
403                                 if( position <= 0 ) transport->goto_end();
404                         }
405                         return transport->reverse_play->handle_event();
406                 case RIGHT_BUTTON:  // activates popup
407                         break;
408                 case WHEEL_UP:
409                         return transport->frame_forward_play->handle_event();
410                 case WHEEL_DOWN:
411                         return transport->frame_reverse_play->handle_event();
412                 }
413         }
414         if(canvas->get_canvas())
415                 return canvas->button_press_event_base(canvas->get_canvas());
416         return 0;
417 }
418
419 int VWindowGUI::cursor_leave_event()
420 {
421         if(canvas->get_canvas())
422                 return canvas->cursor_leave_event_base(canvas->get_canvas());
423         return 0;
424 }
425
426 int VWindowGUI::cursor_enter_event()
427 {
428         if(canvas->get_canvas())
429                 return canvas->cursor_enter_event_base(canvas->get_canvas());
430         return 0;
431 }
432
433 int VWindowGUI::button_release_event()
434 {
435         if(canvas->get_canvas())
436                 return canvas->button_release_event();
437         return 0;
438 }
439
440 int VWindowGUI::cursor_motion_event()
441 {
442         if(canvas->get_canvas())
443         {
444                 canvas->get_canvas()->unhide_cursor();
445                 return canvas->cursor_motion_event();
446         }
447         return 0;
448 }
449
450
451 void VWindowGUI::drag_motion()
452 {
453 // Window hidden
454         if(get_hidden()) return;
455         if(mwindow->session->current_operation != DRAG_ASSET) return;
456         int need_highlight = cursor_above() && get_cursor_over_window() ? 1 : 0;
457         if( highlighted == need_highlight ) return;
458         highlighted = need_highlight;
459         canvas->draw_refresh();
460 }
461
462 int VWindowGUI::drag_stop()
463 {
464         if(get_hidden()) return 0;
465
466         if(highlighted &&
467                 mwindow->session->current_operation == DRAG_ASSET)
468         {
469                 highlighted = 0;
470                 canvas->draw_refresh();
471                 unlock_window();
472
473                 Indexable *indexable = mwindow->session->drag_assets->size() ?
474                         mwindow->session->drag_assets->get(0) :
475                         0;
476                 EDL *edl = mwindow->session->drag_clips->size() ?
477                         mwindow->session->drag_clips->get(0) :
478                         0;
479                 if(indexable)
480                         vwindow->change_source(indexable);
481                 else
482                 if(edl)
483                         vwindow->change_source(edl);
484                 lock_window("VWindowGUI::drag_stop");
485                 return 1;
486         }
487
488         return 0;
489 }
490
491
492 void VWindowGUI::update_meters()
493 {
494         if(mwindow->edl->session->vwindow_meter != meters->visible)
495         {
496                 meters->set_meters(meters->meter_count,
497                         mwindow->edl->session->vwindow_meter);
498                 mwindow->theme->get_vwindow_sizes(this);
499                 resize_event(get_w(), get_h());
500         }
501 }
502
503
504
505 VWindowMeters::VWindowMeters(MWindow *mwindow,
506         VWindowGUI *gui,
507         int x,
508         int y,
509         int h)
510  : MeterPanel(mwindow,
511                 gui,
512                 x,
513                 y,
514                 -1,
515                 h,
516                 mwindow->edl->session->audio_channels,
517                 mwindow->edl->session->vwindow_meter,
518                 0,
519                 0)
520 {
521         this->mwindow = mwindow;
522         this->gui = gui;
523 }
524
525 VWindowMeters::~VWindowMeters()
526 {
527 }
528
529 int VWindowMeters::change_status_event(int new_status)
530 {
531         mwindow->edl->session->vwindow_meter = new_status;
532         gui->update_meters();
533         return 1;
534 }
535
536
537 VWindowEditing::VWindowEditing(MWindow *mwindow, VWindow *vwindow)
538  : EditPanel(mwindow, vwindow->gui, VWINDOW_ID,
539                 mwindow->theme->vedit_x, mwindow->theme->vedit_y,
540                 EDITING_ARROW,
541                 0, // use_editing_mode
542                 0, // use_keyframe
543                 1, // use_splice
544                 1, // use_overwrite
545                 0, // use_lift
546                 0, // use_extract
547                 1, // use_copy
548                 0, // use_paste
549                 0, // use_undo
550                 0, // use_fit
551                 0, // locklabels
552                 1, // use_labels
553                 1, // use_toclip
554                 1, // use_meters
555                 0, // use_cut
556                 0, // use_commerical
557                 0, // use_goto
558                 1) // use_clk2play
559 {
560         this->mwindow = mwindow;
561         this->vwindow = vwindow;
562 }
563
564 VWindowEditing::~VWindowEditing()
565 {
566 }
567
568 void VWindowEditing::copy_selection()
569 {
570         vwindow->copy(subwindow->shift_down());
571 }
572
573 void VWindowEditing::splice_selection()
574 {
575         if(vwindow->get_edl())
576         {
577                 mwindow->gui->lock_window("VWindowEditing::splice_selection");
578                 mwindow->splice(vwindow->get_edl(), subwindow->shift_down());
579                 mwindow->gui->unlock_window();
580         }
581 }
582
583 void VWindowEditing::overwrite_selection()
584 {
585         if(vwindow->get_edl())
586         {
587                 mwindow->gui->lock_window("VWindowEditing::overwrite_selection");
588                 mwindow->overwrite(vwindow->get_edl(), subwindow->shift_down());
589                 mwindow->gui->unlock_window();
590         }
591 }
592
593 void VWindowEditing::toggle_label()
594 {
595         if(vwindow->get_edl())
596         {
597                 EDL *edl = vwindow->get_edl();
598                 edl->labels->toggle_label(edl->local_session->get_selectionstart(1),
599                         edl->local_session->get_selectionend(1));
600                 vwindow->gui->timebar->update(1);
601         }
602 }
603
604 void VWindowEditing::prev_label()
605 {
606         if(vwindow->get_edl())
607         {
608                 EDL *edl = vwindow->get_edl();
609                 vwindow->gui->unlock_window();
610                 vwindow->playback_engine->interrupt_playback(1);
611                 vwindow->gui->lock_window("VWindowEditing::prev_label");
612
613                 Label *current = edl->labels->prev_label(
614                         edl->local_session->get_selectionstart(1));
615
616
617                 if(!current)
618                 {
619                         edl->local_session->set_selectionstart(0);
620                         edl->local_session->set_selectionend(0);
621                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
622                         vwindow->gui->timebar->update(1);
623                 }
624                 else
625                 {
626                         edl->local_session->set_selectionstart(current->position);
627                         edl->local_session->set_selectionend(current->position);
628                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
629                         vwindow->gui->timebar->update(1);
630                 }
631         }
632 }
633
634 void VWindowEditing::next_label()
635 {
636         if(vwindow->get_edl())
637         {
638                 EDL *edl = vwindow->get_edl();
639                 Label *current = edl->labels->next_label(
640                         edl->local_session->get_selectionstart(1));
641                 if(!current)
642                 {
643                         vwindow->gui->unlock_window();
644                         vwindow->playback_engine->interrupt_playback(1);
645                         vwindow->gui->lock_window("VWindowEditing::next_label 1");
646
647                         double position = edl->tracks->total_length();
648                         edl->local_session->set_selectionstart(position);
649                         edl->local_session->set_selectionend(position);
650                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
651                         vwindow->gui->timebar->update(1);
652                 }
653                 else
654                 {
655                         vwindow->gui->unlock_window();
656                         vwindow->playback_engine->interrupt_playback(1);
657                         vwindow->gui->lock_window("VWindowEditing::next_label 2");
658
659                         edl->local_session->set_selectionstart(current->position);
660                         edl->local_session->set_selectionend(current->position);
661                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
662                         vwindow->gui->timebar->update(1);
663                 }
664         }
665 }
666
667 double VWindowEditing::get_position()
668 {
669         EDL *edl = vwindow->get_edl();
670         double position = !edl ? 0 : edl->local_session->get_selectionstart(1);
671         return position;
672 }
673
674 void VWindowEditing::set_position(double position)
675 {
676         EDL *edl = vwindow->get_edl();
677         if( !edl ) return;
678         if( get_position() != position ) {
679                 if( position < 0 ) position = 0;
680                 edl->local_session->set_selectionstart(position);
681                 edl->local_session->set_selectionend(position);
682                 vwindow->update_position(CHANGE_NONE, 0, 1);
683         }
684 }
685
686 void VWindowEditing::set_inpoint()
687 {
688         vwindow->set_inpoint();
689 }
690
691 void VWindowEditing::set_outpoint()
692 {
693         vwindow->set_outpoint();
694 }
695
696 void VWindowEditing::unset_inoutpoint()
697 {
698         vwindow->unset_inoutpoint();
699 }
700
701
702 void VWindowEditing::to_clip()
703 {
704         EDL *edl = vwindow->get_edl();
705         if( !edl ) return;
706         mwindow->to_clip(edl, _("viewer window: "), subwindow->shift_down());
707 }
708
709 VWindowSource::VWindowSource(MWindow *mwindow, VWindowGUI *vwindow, int x, int y)
710  : BC_PopupTextBox(vwindow,
711         &vwindow->sources,
712         "",
713         x,
714         y,
715         200,
716         200)
717 {
718         this->mwindow = mwindow;
719         this->vwindow = vwindow;
720 }
721
722 VWindowSource::~VWindowSource()
723 {
724 }
725
726 int VWindowSource::handle_event()
727 {
728         return 1;
729 }
730
731
732 VWindowTransport::VWindowTransport(MWindow *mwindow,
733         VWindowGUI *gui,
734         int x,
735         int y)
736  : PlayTransport(mwindow,
737         gui,
738         x,
739         y)
740 {
741         this->gui = gui;
742 }
743
744 EDL* VWindowTransport::get_edl()
745 {
746         return gui->vwindow->get_edl();
747 }
748
749
750 void VWindowTransport::goto_start()
751 {
752         gui->unlock_window();
753         handle_transport(REWIND, 1);
754         gui->lock_window("VWindowTransport::goto_start");
755         gui->vwindow->goto_start();
756 }
757
758 void VWindowTransport::goto_end()
759 {
760         gui->unlock_window();
761         handle_transport(GOTO_END, 1);
762         gui->lock_window("VWindowTransport::goto_end");
763         gui->vwindow->goto_end();
764 }
765
766
767
768
769 VWindowCanvas::VWindowCanvas(MWindow *mwindow, VWindowGUI *gui)
770  : Canvas(mwindow,
771         gui,
772         mwindow->theme->vcanvas_x,
773         mwindow->theme->vcanvas_y,
774         mwindow->theme->vcanvas_w,
775         mwindow->theme->vcanvas_h,
776         0, 0, 0)
777 {
778 //printf("VWindowCanvas::VWindowCanvas %d %d\n", __LINE__, mwindow->theme->vcanvas_x);
779         this->mwindow = mwindow;
780         this->gui = gui;
781 }
782
783 void VWindowCanvas::zoom_resize_window(float percentage)
784 {
785         EDL *edl = gui->vwindow->get_edl();
786         if(!edl) edl = mwindow->edl;
787
788         int canvas_w, canvas_h;
789         int new_w, new_h;
790
791 // Get required canvas size
792         calculate_sizes(edl->get_aspect_ratio(),
793                 edl->session->output_w,
794                 edl->session->output_h,
795                 percentage,
796                 canvas_w,
797                 canvas_h);
798
799 // Estimate window size from current borders
800         new_w = canvas_w + (gui->get_w() - mwindow->theme->vcanvas_w);
801         new_h = canvas_h + (gui->get_h() - mwindow->theme->vcanvas_h);
802
803         mwindow->session->vwindow_w = new_w;
804         mwindow->session->vwindow_h = new_h;
805
806         mwindow->theme->get_vwindow_sizes(gui);
807
808 // Estimate again from new borders
809         new_w = canvas_w + (mwindow->session->vwindow_w - mwindow->theme->vcanvas_w);
810         new_h = canvas_h + (mwindow->session->vwindow_h - mwindow->theme->vcanvas_h);
811
812
813         gui->resize_window(new_w, new_h);
814         gui->resize_event(new_w, new_h);
815 }
816
817 void VWindowCanvas::close_source()
818 {
819         gui->unlock_window();
820         gui->vwindow->playback_engine->interrupt_playback(1);
821         gui->lock_window("VWindowCanvas::close_source");
822         gui->vwindow->delete_source(1, 1);
823 }
824
825
826 void VWindowCanvas::draw_refresh(int flush)
827 {
828         EDL *edl = gui->vwindow->get_edl();
829
830         if(!get_canvas()->get_video_on()) get_canvas()->clear_box(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
831         if(!get_canvas()->get_video_on() && refresh_frame && edl)
832         {
833                 float in_x1, in_y1, in_x2, in_y2;
834                 float out_x1, out_y1, out_x2, out_y2;
835                 get_transfers(edl,
836                         in_x1,
837                         in_y1,
838                         in_x2,
839                         in_y2,
840                         out_x1,
841                         out_y1,
842                         out_x2,
843                         out_y2);
844                 get_canvas()->draw_vframe(refresh_frame,
845                                 (int)out_x1,
846                                 (int)out_y1,
847                                 (int)(out_x2 - out_x1),
848                                 (int)(out_y2 - out_y1),
849                                 (int)in_x1,
850                                 (int)in_y1,
851                                 (int)(in_x2 - in_x1),
852                                 (int)(in_y2 - in_y1),
853                                 0);
854         }
855
856         if(!get_canvas()->get_video_on())
857         {
858                 draw_overlays();
859                 get_canvas()->flash(flush);
860         }
861 }
862
863 void VWindowCanvas::draw_overlays()
864 {
865         if( gui->highlighted )
866         {
867                 get_canvas()->set_color(WHITE);
868                 get_canvas()->set_inverse();
869                 get_canvas()->draw_rectangle(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
870                 get_canvas()->draw_rectangle(1, 1, get_canvas()->get_w() - 2, get_canvas()->get_h() - 2);
871                 get_canvas()->set_opaque();
872         }
873 }
874
875 int VWindowCanvas::get_fullscreen()
876 {
877         return mwindow->session->vwindow_fullscreen;
878 }
879
880 void VWindowCanvas::set_fullscreen(int value)
881 {
882         mwindow->session->vwindow_fullscreen = value;
883 }
884