last push faux paux, update shortcuts doc, period/comma alt shortcuts, popup deactiva...
[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
169 //printf("VWindowGUI::update_sources 1\n");
170         sources.remove_all_objects();
171 //printf("VWindowGUI::update_sources 2\n");
172
173
174
175         for(int i = 0;
176                 i < mwindow->edl->clips.total;
177                 i++)
178         {
179                 char *clip_title = mwindow->edl->clips.values[i]->local_session->clip_title;
180                 int exists = 0;
181
182                 for(int j = 0; j < sources.total; j++)
183                 {
184                         if(!strcasecmp(sources.values[j]->get_text(), clip_title))
185                         {
186                                 exists = 1;
187                         }
188                 }
189
190                 if(!exists)
191                 {
192                         sources.append(new BC_ListBoxItem(clip_title));
193                 }
194         }
195 //printf("VWindowGUI::update_sources 3\n");
196
197         FileSystem fs;
198         for(Asset *current = mwindow->edl->assets->first;
199                 current;
200                 current = NEXT)
201         {
202                 char clip_title[BCTEXTLEN];
203                 fs.extract_name(clip_title, current->path);
204                 int exists = 0;
205
206                 for(int j = 0; j < sources.total; j++)
207                 {
208                         if(!strcasecmp(sources.values[j]->get_text(), clip_title))
209                         {
210                                 exists = 1;
211                         }
212                 }
213
214                 if(!exists)
215                 {
216                         sources.append(new BC_ListBoxItem(clip_title));
217                 }
218         }
219
220 //printf("VWindowGUI::update_sources 4\n");
221
222 //      source->update_list(&sources);
223 //      source->update(title);
224         unlock_window();
225 }
226
227 void VWindowGUI::create_objects()
228 {
229         in_point = 0;
230         out_point = 0;
231         lock_window("VWindowGUI::create_objects");
232         set_icon(mwindow->theme->get_image("vwindow_icon"));
233
234 //printf("VWindowGUI::create_objects 1\n");
235         mwindow->theme->get_vwindow_sizes(this);
236         mwindow->theme->draw_vwindow_bg(this);
237         flash(0);
238
239         meters = new VWindowMeters(mwindow,
240                 this,
241                 mwindow->theme->vmeter_x,
242                 mwindow->theme->vmeter_y,
243                 mwindow->theme->vmeter_h);
244         meters->create_objects();
245
246 //printf("VWindowGUI::create_objects 1\n");
247 // Requires meters to build
248         edit_panel = new VWindowEditing(mwindow, vwindow);
249         edit_panel->set_meters(meters);
250         edit_panel->create_objects();
251
252 //printf("VWindowGUI::create_objects 1\n");
253         transport = new VWindowTransport(mwindow,
254                 this,
255                 mwindow->theme->vtransport_x,
256                 mwindow->theme->vtransport_y);
257         transport->create_objects();
258
259 //printf("VWindowGUI::create_objects 1\n");
260 //      add_subwindow(fps_title = new BC_Title(mwindow->theme->vedit_x, y, ""));
261     add_subwindow(clock = new MainClock(mwindow,
262                 mwindow->theme->vtime_x,
263                 mwindow->theme->vtime_y,
264                 mwindow->theme->vtime_w));
265
266         canvas = new VWindowCanvas(mwindow, this);
267         canvas->create_objects(mwindow->edl);
268         canvas->use_vwindow();
269
270
271 //printf("VWindowGUI::create_objects 1\n");
272         add_subwindow(timebar = new VTimeBar(mwindow,
273                 this,
274                 mwindow->theme->vtimebar_x,
275                 mwindow->theme->vtimebar_y,
276                 mwindow->theme->vtimebar_w,
277                 mwindow->theme->vtimebar_h));
278         timebar->create_objects();
279 //printf("VWindowGUI::create_objects 2\n");
280
281
282 //printf("VWindowGUI::create_objects 1\n");
283 //      source = new VWindowSource(mwindow,
284 //              this,
285 //              mwindow->theme->vsource_x,
286 //              mwindow->theme->vsource_y);
287 //      source->create_objects();
288         update_sources(_("None"));
289
290 //printf("VWindowGUI::create_objects 2\n");
291         deactivate();
292
293         show_window();
294         unlock_window();
295 }
296
297 int VWindowGUI::resize_event(int w, int h)
298 {
299         mwindow->session->vwindow_x = get_x();
300         mwindow->session->vwindow_y = get_y();
301         mwindow->session->vwindow_w = w;
302         mwindow->session->vwindow_h = h;
303
304         mwindow->theme->get_vwindow_sizes(this);
305         mwindow->theme->draw_vwindow_bg(this);
306         flash(0);
307
308 //printf("VWindowGUI::resize_event %d %d\n", __LINE__, mwindow->theme->vedit_y);
309         edit_panel->reposition_buttons(mwindow->theme->vedit_x,
310                 mwindow->theme->vedit_y);
311
312         timebar->resize_event();
313         transport->reposition_buttons(mwindow->theme->vtransport_x,
314                 mwindow->theme->vtransport_y);
315         clock->reposition_window(mwindow->theme->vtime_x,
316                 mwindow->theme->vtime_y,
317                 mwindow->theme->vtime_w,
318                 clock->get_h());
319         canvas->reposition_window(0,
320                 mwindow->theme->vcanvas_x,
321                 mwindow->theme->vcanvas_y,
322                 mwindow->theme->vcanvas_w,
323                 mwindow->theme->vcanvas_h);
324 //printf("VWindowGUI::resize_event %d %d\n", __LINE__, mwindow->theme->vcanvas_x);
325 //      source->reposition_window(mwindow->theme->vsource_x,
326 //              mwindow->theme->vsource_y);
327         meters->reposition_window(mwindow->theme->vmeter_x,
328                 mwindow->theme->vmeter_y,
329                 -1,
330                 mwindow->theme->vmeter_h);
331
332         BC_WindowBase::resize_event(w, h);
333         return 1;
334 }
335
336
337
338
339
340 int VWindowGUI::translation_event()
341 {
342         mwindow->session->vwindow_x = get_x();
343         mwindow->session->vwindow_y = get_y();
344         return 0;
345 }
346
347 int VWindowGUI::close_event()
348 {
349         hide_window();
350         int i = mwindow->vwindows.size();
351         while( --i >= 0 && mwindow->vwindows.get(i)->gui != this );
352         if( i > 0 ) {
353                 set_done(0);
354                 return 1;
355         }
356
357         mwindow->session->show_vwindow = 0;
358         unlock_window();
359
360         mwindow->gui->lock_window("VWindowGUI::close_event");
361         mwindow->gui->mainmenu->show_vwindow->set_checked(0);
362         mwindow->gui->unlock_window();
363
364         lock_window("VWindowGUI::close_event");
365         mwindow->save_defaults();
366         return 1;
367 }
368
369 int VWindowGUI::keypress_event()
370 {
371         int result = 0;
372         switch(get_keypress())
373         {
374                 case 'w':
375                 case 'W':
376                         close_event();
377                         result = 1;
378                         break;
379                 case 'z':
380                         mwindow->undo_entry(this);
381                         break;
382                 case 'Z':
383                         mwindow->redo_entry(this);
384                         break;
385                 case 'f':
386                         unlock_window();
387                         if(mwindow->session->vwindow_fullscreen)
388                                 canvas->stop_fullscreen();
389                         else
390                                 canvas->start_fullscreen();
391                         lock_window("VWindowGUI::keypress_event 1");
392                         break;
393                 case ESC:
394                         unlock_window();
395                         if(mwindow->session->vwindow_fullscreen)
396                                 canvas->stop_fullscreen();
397                         lock_window("VWindowGUI::keypress_event 2");
398                         break;
399         }
400         if(!result) result = transport->keypress_event();
401         return result;
402 }
403
404 void VWindowGUI::stop_transport(const char *lock_msg)
405 {
406         if( !transport->is_stopped() ) {
407                 if( lock_msg ) unlock_window();
408                 transport->handle_transport(STOP, 1, 0, 0);
409                 if( lock_msg ) lock_window(lock_msg);
410         }
411 }
412
413 int VWindowGUI::button_press_event()
414 {
415         if( vwindow->get_edl() != 0 && canvas->get_canvas() &&
416             mwindow->edl->session->vwindow_click2play &&
417             canvas->get_canvas()->get_cursor_over_window() ) {
418                 switch( get_buttonpress() ) {
419                 case LEFT_BUTTON:
420                         if( !vwindow->playback_engine->is_playing_back ) {
421                                 double length = vwindow->get_edl()->tracks->total_playable_length();
422                                 double position = vwindow->playback_engine->get_tracking_position();
423                                 if( position >= length ) transport->goto_start();
424                         }
425                         return transport->forward_play->handle_event();
426                 case MIDDLE_BUTTON:
427                         if( !vwindow->playback_engine->is_playing_back ) {
428                                 double position = vwindow->playback_engine->get_tracking_position();
429                                 if( position <= 0 ) transport->goto_end();
430                         }
431                         return transport->reverse_play->handle_event();
432                 case RIGHT_BUTTON:  // activates popup
433                         break;
434                 case WHEEL_UP:
435                         return transport->frame_forward_play->handle_event();
436                 case WHEEL_DOWN:
437                         return transport->frame_reverse_play->handle_event();
438                 }
439         }
440         if(canvas->get_canvas())
441                 return canvas->button_press_event_base(canvas->get_canvas());
442         return 0;
443 }
444
445 int VWindowGUI::cursor_leave_event()
446 {
447         if(canvas->get_canvas())
448                 return canvas->cursor_leave_event_base(canvas->get_canvas());
449         return 0;
450 }
451
452 int VWindowGUI::cursor_enter_event()
453 {
454         if(canvas->get_canvas())
455                 return canvas->cursor_enter_event_base(canvas->get_canvas());
456         return 0;
457 }
458
459 int VWindowGUI::button_release_event()
460 {
461         if(canvas->get_canvas())
462                 return canvas->button_release_event();
463         return 0;
464 }
465
466 int VWindowGUI::cursor_motion_event()
467 {
468         if(canvas->get_canvas())
469         {
470                 canvas->get_canvas()->unhide_cursor();
471                 return canvas->cursor_motion_event();
472         }
473         return 0;
474 }
475
476
477 void VWindowGUI::drag_motion()
478 {
479 // Window hidden
480         if(get_hidden()) return;
481         if(mwindow->session->current_operation != DRAG_ASSET) return;
482         int need_highlight = cursor_above() && get_cursor_over_window() ? 1 : 0;
483         if( highlighted == need_highlight ) return;
484         highlighted = need_highlight;
485         canvas->draw_refresh();
486 }
487
488 int VWindowGUI::drag_stop()
489 {
490         if(get_hidden()) return 0;
491
492         if(highlighted &&
493                 mwindow->session->current_operation == DRAG_ASSET)
494         {
495                 highlighted = 0;
496                 canvas->draw_refresh();
497                 unlock_window();
498
499                 Indexable *indexable = mwindow->session->drag_assets->size() ?
500                         mwindow->session->drag_assets->get(0) :
501                         0;
502                 EDL *edl = mwindow->session->drag_clips->size() ?
503                         mwindow->session->drag_clips->get(0) :
504                         0;
505                 if(indexable)
506                         vwindow->change_source(indexable);
507                 else
508                 if(edl)
509                         vwindow->change_source(edl);
510                 lock_window("VWindowGUI::drag_stop");
511                 return 1;
512         }
513
514         return 0;
515 }
516
517
518 void VWindowGUI::update_meters()
519 {
520         if(mwindow->edl->session->vwindow_meter != meters->visible)
521         {
522                 meters->set_meters(meters->meter_count,
523                         mwindow->edl->session->vwindow_meter);
524                 mwindow->theme->get_vwindow_sizes(this);
525                 resize_event(get_w(), get_h());
526         }
527 }
528
529
530
531 VWindowMeters::VWindowMeters(MWindow *mwindow,
532         VWindowGUI *gui,
533         int x,
534         int y,
535         int h)
536  : MeterPanel(mwindow,
537                 gui,
538                 x,
539                 y,
540                 -1,
541                 h,
542                 mwindow->edl->session->audio_channels,
543                 mwindow->edl->session->vwindow_meter,
544                 0,
545                 0)
546 {
547         this->mwindow = mwindow;
548         this->gui = gui;
549 }
550
551 VWindowMeters::~VWindowMeters()
552 {
553 }
554
555 int VWindowMeters::change_status_event(int new_status)
556 {
557         mwindow->edl->session->vwindow_meter = new_status;
558         gui->update_meters();
559         return 1;
560 }
561
562
563 VWindowEditing::VWindowEditing(MWindow *mwindow, VWindow *vwindow)
564  : EditPanel(mwindow, vwindow->gui, VWINDOW_ID,
565                 mwindow->theme->vedit_x, mwindow->theme->vedit_y,
566                 EDITING_ARROW,
567                 0, // use_editing_mode
568                 0, // use_keyframe
569                 1, // use_splice
570                 1, // use_overwrite
571                 0, // use_lift
572                 0, // use_extract
573                 1, // use_copy
574                 0, // use_paste
575                 0, // use_undo
576                 0, // use_fit
577                 0, // locklabels
578                 1, // use_labels
579                 1, // use_toclip
580                 1, // use_meters
581                 0, // use_cut
582                 0, // use_commerical
583                 0, // use_goto
584                 1) // use_clk2play
585 {
586         this->mwindow = mwindow;
587         this->vwindow = vwindow;
588 }
589
590 VWindowEditing::~VWindowEditing()
591 {
592 }
593
594 void VWindowEditing::copy_selection()
595 {
596         vwindow->copy();
597 }
598
599 void VWindowEditing::splice_selection()
600 {
601         if(vwindow->get_edl())
602         {
603                 mwindow->gui->lock_window("VWindowEditing::splice_selection");
604                 mwindow->splice(vwindow->get_edl());
605                 mwindow->gui->unlock_window();
606         }
607 }
608
609 void VWindowEditing::overwrite_selection()
610 {
611         if(vwindow->get_edl())
612         {
613                 mwindow->gui->lock_window("VWindowEditing::overwrite_selection");
614                 mwindow->overwrite(vwindow->get_edl());
615                 mwindow->gui->unlock_window();
616         }
617 }
618
619 void VWindowEditing::toggle_label()
620 {
621         if(vwindow->get_edl())
622         {
623                 EDL *edl = vwindow->get_edl();
624                 edl->labels->toggle_label(edl->local_session->get_selectionstart(1),
625                         edl->local_session->get_selectionend(1));
626                 vwindow->gui->timebar->update(1);
627         }
628 }
629
630 void VWindowEditing::prev_label()
631 {
632         if(vwindow->get_edl())
633         {
634                 EDL *edl = vwindow->get_edl();
635                 vwindow->gui->unlock_window();
636                 vwindow->playback_engine->interrupt_playback(1);
637                 vwindow->gui->lock_window("VWindowEditing::prev_label");
638
639                 Label *current = edl->labels->prev_label(
640                         edl->local_session->get_selectionstart(1));
641
642
643                 if(!current)
644                 {
645                         edl->local_session->set_selectionstart(0);
646                         edl->local_session->set_selectionend(0);
647                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
648                         vwindow->gui->timebar->update(1);
649                 }
650                 else
651                 {
652                         edl->local_session->set_selectionstart(current->position);
653                         edl->local_session->set_selectionend(current->position);
654                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
655                         vwindow->gui->timebar->update(1);
656                 }
657         }
658 }
659
660 void VWindowEditing::next_label()
661 {
662         if(vwindow->get_edl())
663         {
664                 EDL *edl = vwindow->get_edl();
665                 Label *current = edl->labels->next_label(
666                         edl->local_session->get_selectionstart(1));
667                 if(!current)
668                 {
669                         vwindow->gui->unlock_window();
670                         vwindow->playback_engine->interrupt_playback(1);
671                         vwindow->gui->lock_window("VWindowEditing::next_label 1");
672
673                         double position = edl->tracks->total_length();
674                         edl->local_session->set_selectionstart(position);
675                         edl->local_session->set_selectionend(position);
676                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
677                         vwindow->gui->timebar->update(1);
678                 }
679                 else
680                 {
681                         vwindow->gui->unlock_window();
682                         vwindow->playback_engine->interrupt_playback(1);
683                         vwindow->gui->lock_window("VWindowEditing::next_label 2");
684
685                         edl->local_session->set_selectionstart(current->position);
686                         edl->local_session->set_selectionend(current->position);
687                         vwindow->update_position(CHANGE_NONE, 0, 1, 0);
688                         vwindow->gui->timebar->update(1);
689                 }
690         }
691 }
692
693 double VWindowEditing::get_position()
694 {
695         EDL *edl = vwindow->get_edl();
696         double position = !edl ? 0 : edl->local_session->get_selectionstart(1);
697         return position;
698 }
699
700 void VWindowEditing::set_position(double position)
701 {
702         EDL *edl = vwindow->get_edl();
703         if( !edl ) return;
704         if( get_position() != position ) {
705                 if( position < 0 ) position = 0;
706                 edl->local_session->set_selectionstart(position);
707                 edl->local_session->set_selectionend(position);
708                 vwindow->update_position(CHANGE_NONE, 0, 1);
709         }
710 }
711
712 void VWindowEditing::set_inpoint()
713 {
714         vwindow->set_inpoint();
715 }
716
717 void VWindowEditing::set_outpoint()
718 {
719         vwindow->set_outpoint();
720 }
721
722 void VWindowEditing::unset_inoutpoint()
723 {
724         vwindow->unset_inoutpoint();
725 }
726
727
728 void VWindowEditing::to_clip()
729 {
730         EDL *edl = vwindow->get_edl();
731         if( !edl ) return;
732         mwindow->to_clip(edl, _("viewer window: "));
733 }
734
735 VWindowSource::VWindowSource(MWindow *mwindow, VWindowGUI *vwindow, int x, int y)
736  : BC_PopupTextBox(vwindow,
737         &vwindow->sources,
738         "",
739         x,
740         y,
741         200,
742         200)
743 {
744         this->mwindow = mwindow;
745         this->vwindow = vwindow;
746 }
747
748 VWindowSource::~VWindowSource()
749 {
750 }
751
752 int VWindowSource::handle_event()
753 {
754         return 1;
755 }
756
757
758 VWindowTransport::VWindowTransport(MWindow *mwindow,
759         VWindowGUI *gui,
760         int x,
761         int y)
762  : PlayTransport(mwindow,
763         gui,
764         x,
765         y)
766 {
767         this->gui = gui;
768 }
769
770 EDL* VWindowTransport::get_edl()
771 {
772         return gui->vwindow->get_edl();
773 }
774
775
776 void VWindowTransport::goto_start()
777 {
778         gui->unlock_window();
779         handle_transport(REWIND, 1);
780         gui->lock_window("VWindowTransport::goto_start");
781         gui->vwindow->goto_start();
782 }
783
784 void VWindowTransport::goto_end()
785 {
786         gui->unlock_window();
787         handle_transport(GOTO_END, 1);
788         gui->lock_window("VWindowTransport::goto_end");
789         gui->vwindow->goto_end();
790 }
791
792
793
794
795 VWindowCanvas::VWindowCanvas(MWindow *mwindow, VWindowGUI *gui)
796  : Canvas(mwindow,
797         gui,
798         mwindow->theme->vcanvas_x,
799         mwindow->theme->vcanvas_y,
800         mwindow->theme->vcanvas_w,
801         mwindow->theme->vcanvas_h,
802         0, 0, 0)
803 {
804 //printf("VWindowCanvas::VWindowCanvas %d %d\n", __LINE__, mwindow->theme->vcanvas_x);
805         this->mwindow = mwindow;
806         this->gui = gui;
807 }
808
809 void VWindowCanvas::zoom_resize_window(float percentage)
810 {
811         EDL *edl = gui->vwindow->get_edl();
812         if(!edl) edl = mwindow->edl;
813
814         int canvas_w, canvas_h;
815         int new_w, new_h;
816
817 // Get required canvas size
818         calculate_sizes(edl->get_aspect_ratio(),
819                 edl->session->output_w,
820                 edl->session->output_h,
821                 percentage,
822                 canvas_w,
823                 canvas_h);
824
825 // Estimate window size from current borders
826         new_w = canvas_w + (gui->get_w() - mwindow->theme->vcanvas_w);
827         new_h = canvas_h + (gui->get_h() - mwindow->theme->vcanvas_h);
828
829         mwindow->session->vwindow_w = new_w;
830         mwindow->session->vwindow_h = new_h;
831
832         mwindow->theme->get_vwindow_sizes(gui);
833
834 // Estimate again from new borders
835         new_w = canvas_w + (mwindow->session->vwindow_w - mwindow->theme->vcanvas_w);
836         new_h = canvas_h + (mwindow->session->vwindow_h - mwindow->theme->vcanvas_h);
837
838
839         gui->resize_window(new_w, new_h);
840         gui->resize_event(new_w, new_h);
841 }
842
843 void VWindowCanvas::close_source()
844 {
845         gui->unlock_window();
846         gui->vwindow->playback_engine->interrupt_playback(1);
847         gui->lock_window("VWindowCanvas::close_source");
848         gui->vwindow->delete_source(1, 1);
849 }
850
851
852 void VWindowCanvas::draw_refresh(int flush)
853 {
854         EDL *edl = gui->vwindow->get_edl();
855
856         if(!get_canvas()->get_video_on()) get_canvas()->clear_box(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
857         if(!get_canvas()->get_video_on() && refresh_frame && edl)
858         {
859                 float in_x1, in_y1, in_x2, in_y2;
860                 float out_x1, out_y1, out_x2, out_y2;
861                 get_transfers(edl,
862                         in_x1,
863                         in_y1,
864                         in_x2,
865                         in_y2,
866                         out_x1,
867                         out_y1,
868                         out_x2,
869                         out_y2);
870                 get_canvas()->draw_vframe(refresh_frame,
871                                 (int)out_x1,
872                                 (int)out_y1,
873                                 (int)(out_x2 - out_x1),
874                                 (int)(out_y2 - out_y1),
875                                 (int)in_x1,
876                                 (int)in_y1,
877                                 (int)(in_x2 - in_x1),
878                                 (int)(in_y2 - in_y1),
879                                 0);
880         }
881
882         if(!get_canvas()->get_video_on())
883         {
884                 draw_overlays();
885                 get_canvas()->flash(flush);
886         }
887 }
888
889 void VWindowCanvas::draw_overlays()
890 {
891         if( gui->highlighted )
892         {
893                 get_canvas()->set_color(WHITE);
894                 get_canvas()->set_inverse();
895                 get_canvas()->draw_rectangle(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
896                 get_canvas()->draw_rectangle(1, 1, get_canvas()->get_w() - 2, get_canvas()->get_h() - 2);
897                 get_canvas()->set_opaque();
898         }
899 }
900
901 int VWindowCanvas::get_fullscreen()
902 {
903         return mwindow->session->vwindow_fullscreen;
904 }
905
906 void VWindowCanvas::set_fullscreen(int value)
907 {
908         mwindow->session->vwindow_fullscreen = value;
909 }
910