r999: maintainers added to README_en.
[cinelerra_cv/mob.git] / cinelerra / canvas.C
blob8b652c57725fd1c7e3882615b31ae217600b73e0
1 #include "bcsignals.h"
2 #include "canvas.h"
3 #include "clip.h"
4 #include "edl.h"
5 #include "edlsession.h"
6 #include "keys.h"
7 #include "language.h"
8 #include "mainsession.h"
9 #include "mutex.h"
10 #include "mwindow.h"
11 #include "vframe.h"
15 Canvas::Canvas(MWindow *mwindow,
16         BC_WindowBase *subwindow, 
17         int x, 
18         int y, 
19         int w, 
20         int h,
21         int output_w,
22         int output_h,
23         int use_scrollbars,
24         int use_cwindow,
25         int use_rwindow,
26         int use_vwindow)
28         reset();
30         if(x < 10) x = 10;
31         if(y < 10) y = 10;
32         this->mwindow = mwindow;
33         this->subwindow = subwindow;
34         this->x = x;
35         this->y = y;
36         this->w = w;
37         this->h = h;
38         this->output_w = output_w;
39         this->output_h = output_h;
40         this->use_scrollbars = use_scrollbars;
41         this->use_cwindow = use_cwindow;
42         this->use_rwindow = use_rwindow;
43         this->use_vwindow = use_vwindow;
44         this->root_w = subwindow->get_root_w(0, 0);
45         this->root_h = subwindow->get_root_h(0);
46         canvas_lock = new Mutex("Canvas::canvas_lock", 1);
49 Canvas::~Canvas()
51         if(refresh_frame) delete refresh_frame;
52         delete canvas_menu;
53         if(yscroll) delete yscroll;
54         if(xscroll) delete xscroll;
55         delete canvas_subwindow;
56         delete canvas_fullscreen;
57         delete canvas_lock;
60 void Canvas::reset()
62         use_scrollbars = 0;
63         output_w = 0;
64         output_h = 0;
65     xscroll = 0;
66     yscroll = 0;
67         refresh_frame = 0;
68         canvas_subwindow = 0;
69         canvas_fullscreen = 0;
70         is_processing = 0;
71         cursor_inside = 0;
74 void Canvas::lock_canvas(char *location)
76         canvas_lock->lock(location);
79 void Canvas::unlock_canvas()
81         canvas_lock->unlock();
84 int Canvas::is_locked()
86         return canvas_lock->is_locked();
90 BC_WindowBase* Canvas::get_canvas()
92         if(get_fullscreen() && canvas_fullscreen) 
93                 return canvas_fullscreen;
94         else
95                 return canvas_subwindow;
99 // Get dimensions given a zoom
100 void Canvas::calculate_sizes(float aspect_ratio, 
101         int output_w, 
102         int output_h, 
103         float zoom, 
104         int &w, 
105         int &h)
107 // Horizontal stretch
108         if((float)output_w / output_h <= aspect_ratio)
109         {
110                 w = (int)((float)output_h * aspect_ratio * zoom);
111                 h = (int)((float)output_h * zoom);
112         }
113         else
114 // Vertical stretch
115         {
116                 h = (int)((float)output_w / aspect_ratio * zoom);
117                 w = (int)((float)output_w * zoom);
118         }
121 float Canvas::get_x_offset(EDL *edl, 
122         int single_channel, 
123         float zoom_x, 
124         float conformed_w,
125         float conformed_h)
127         if(use_scrollbars)
128         {
129                 if(xscroll) 
130                 {
131 // If the projection is smaller than the canvas, this forces it in the center.
132 //                      if(conformed_w < w_visible)
133 //                              return -(float)(w_visible - conformed_w) / 2;
135                         return (float)get_xscroll();
136                 }
137                 else
138                         return ((float)-get_canvas()->get_w() / zoom_x + 
139                                 edl->session->output_w) / 2;
140         }
141         else
142         {
143                 int out_w, out_h;
144                 int canvas_w = get_canvas()->get_w();
145                 int canvas_h = get_canvas()->get_h();
146                 out_w = canvas_w;
147                 out_h = canvas_h;
148                 
149                 if((float)out_w / out_h > conformed_w / conformed_h)
150                 {
151                         out_w = (int)(out_h * conformed_w / conformed_h + 0.5);
152                 }
153                 
154                 if(out_w < canvas_w)
155                         return -(canvas_w - out_w) / 2 / zoom_x;
156         }
158         return 0;
161 float Canvas::get_y_offset(EDL *edl, 
162         int single_channel, 
163         float zoom_y, 
164         float conformed_w,
165         float conformed_h)
167         if(use_scrollbars)
168         {
169                 if(yscroll)
170                 {
171 // If the projection is smaller than the canvas, this forces it in the center.
172 //                      if(conformed_h < h_visible)
173 //                              return -(float)(h_visible - conformed_h) / 2;
175                         return (float)get_yscroll();
176                 }
177                 else
178                         return ((float)-get_canvas()->get_h() / zoom_y + 
179                                 edl->session->output_h) / 2;
180         }
181         else
182         {
183                 int out_w, out_h;
184                 int canvas_w = get_canvas()->get_w();
185                 int canvas_h = get_canvas()->get_h();
186                 out_w = canvas_w;
187                 out_h = canvas_h;
189                 if((float)out_w / out_h <= conformed_w / conformed_h)
190                 {
191                         out_h = (int)((float)out_w / (conformed_w / conformed_h) + 0.5);
192                 }
194 //printf("Canvas::get_y_offset 1 %d %d %f\n", out_h, canvas_h, -((float)canvas_h - out_h) / 2);
195                 if(out_h < canvas_h)
196                         return -((float)canvas_h - out_h) / 2 / zoom_y;
197         }
199         return 0;
202 // This may not be used anymore
203 void Canvas::check_boundaries(EDL *edl, int &x, int &y, float &zoom)
205         if(x + w_visible > w_needed) x = w_needed - w_visible;
206         if(y + h_visible > h_needed) y = h_needed - h_visible;
208         if(x < 0) x = 0;
209         if(y < 0) y = 0;
212 void Canvas::update_scrollbars()
214         if(use_scrollbars)
215         {
216                 if(xscroll) xscroll->update_length(w_needed, get_xscroll(), w_visible);
217                 if(yscroll) yscroll->update_length(h_needed, get_yscroll(), h_visible);
218         }
221 void Canvas::get_zooms(EDL *edl, 
222         int single_channel, 
223         float &zoom_x, 
224         float &zoom_y,
225         float &conformed_w,
226         float &conformed_h)
228         edl->calculate_conformed_dimensions(single_channel, 
229                 conformed_w, 
230                 conformed_h);
232         if(use_scrollbars)
233         {
234                 zoom_x = get_zoom() * 
235                         conformed_w / 
236                         edl->session->output_w;
237                 zoom_y = get_zoom() * 
238                         conformed_h / 
239                         edl->session->output_h;
240         }
241         else
242         {
243                 int out_w, out_h;
244                 int canvas_w = get_canvas()->get_w();
245                 int canvas_h = get_canvas()->get_h();
246         
247                 out_w = canvas_w;
248                 out_h = canvas_h;
250                 if((float)out_w / out_h > conformed_w / conformed_h)
251                 {
252                         out_w = (int)((float)out_h * conformed_w / conformed_h + 0.5);
253                 }
254                 else
255                 {
256                         out_h = (int)((float)out_w / (conformed_w / conformed_h) + 0.5);
257                 }
259                 zoom_x = (float)out_w / edl->session->output_w;
260                 zoom_y = (float)out_h / edl->session->output_h;
261 //printf("get zooms 2 %d %d %f %f\n", canvas_w, canvas_h, conformed_w, conformed_h);
262         }
265 // Convert a coordinate on the canvas to a coordinate on the output
266 void Canvas::canvas_to_output(EDL *edl, int single_channel, float &x, float &y)
268         float zoom_x, zoom_y, conformed_w, conformed_h;
269         get_zooms(edl, single_channel, zoom_x, zoom_y, conformed_w, conformed_h);
271 //printf("Canvas::canvas_to_output y=%f zoom_y=%f y_offset=%f\n", 
272 //      y, zoom_y, get_y_offset(edl, single_channel, zoom_y, conformed_w, conformed_h));
274         x = (float)x / zoom_x + get_x_offset(edl, single_channel, zoom_x, conformed_w, conformed_h);
275         y = (float)y / zoom_y + get_y_offset(edl, single_channel, zoom_y, conformed_w, conformed_h);
278 void Canvas::output_to_canvas(EDL *edl, int single_channel, float &x, float &y)
280         float zoom_x, zoom_y, conformed_w, conformed_h;
281         get_zooms(edl, single_channel, zoom_x, zoom_y, conformed_w, conformed_h);
283 //printf("Canvas::output_to_canvas x=%f zoom_x=%f x_offset=%f\n", x, zoom_x, get_x_offset(edl, single_channel, zoom_x, conformed_w));
285         x = (float)zoom_x * (x - get_x_offset(edl, single_channel, zoom_x, conformed_w, conformed_h));
286         y = (float)zoom_y * (y - get_y_offset(edl, single_channel, zoom_y, conformed_w, conformed_h));
291 void Canvas::get_transfers(EDL *edl, 
292         float &output_x1, 
293         float &output_y1, 
294         float &output_x2, 
295         float &output_y2,
296         float &canvas_x1, 
297         float &canvas_y1, 
298         float &canvas_x2, 
299         float &canvas_y2,
300         int canvas_w,
301         int canvas_h)
303 // printf("Canvas::get_transfers %d %d\n", canvas_w, 
304 //              canvas_h);
305 // automatic canvas size detection
306         if(canvas_w < 0) canvas_w = get_canvas()->get_w();
307         if(canvas_h < 0) canvas_h = get_canvas()->get_h();
309 // Canvas is zoomed to a portion of the output frame
310         if(use_scrollbars)
311         {
312                 float in_x1, in_y1, in_x2, in_y2;
313                 float out_x1, out_y1, out_x2, out_y2;
314                 float zoom_x, zoom_y, conformed_w, conformed_h;
316                 get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
317                 out_x1 = 0;
318                 out_y1 = 0;
319                 out_x2 = canvas_w;
320                 out_y2 = canvas_h;
321                 in_x1 = 0;
322                 in_y1 = 0;
323                 in_x2 = canvas_w;
324                 in_y2 = canvas_h;
326                 canvas_to_output(edl, 0, in_x1, in_y1);
327                 canvas_to_output(edl, 0, in_x2, in_y2);
329 //printf("Canvas::get_transfers 1 %.0f %.0f %.0f %.0f -> %.0f %.0f %.0f %.0f\n",
330 //in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2);
332                 if(in_x1 < 0)
333                 {
334                         out_x1 += -in_x1 * zoom_x;
335                         in_x1 = 0;
336                 }
338                 if(in_y1 < 0)
339                 {
340                         out_y1 += -in_y1 * zoom_y;
341                         in_y1 = 0;
342                 }
344                 int output_w = get_output_w(edl);
345                 int output_h = get_output_h(edl);
347                 if(in_x2 > output_w)
348                 {
349                         out_x2 -= (in_x2 - output_w) * zoom_x;
350                         in_x2 = output_w;
351                 }
353                 if(in_y2 > output_h)
354                 {
355                         out_y2 -= (in_y2 - output_h) * zoom_y;
356                         in_y2 = output_h;
357                 }
358 // printf("Canvas::get_transfers 2 %.0f %.0f %.0f %.0f -> %.0f %.0f %.0f %.0f\n",
359 //                      in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2);
361                 output_x1 = in_x1;
362                 output_y1 = in_y1;
363                 output_x2 = in_x2;
364                 output_y2 = in_y2;
365                 canvas_x1 = out_x1;
366                 canvas_y1 = out_y1;
367                 canvas_x2 = out_x2;
368                 canvas_y2 = out_y2;
370 // Center on canvas
371 //              if(!scrollbars_exist())
372 //              {
373 //                      out_x = canvas_w / 2 - out_w / 2;
374 //                      out_y = canvas_h / 2 - out_h / 2;
375 //              }
377         }
378         else
379 // The output frame is normalized to the canvas
380         {
381 // Default canvas coords fill the entire canvas
382                 canvas_x1 = 0;
383                 canvas_y1 = 0;
384                 canvas_x2 = canvas_w;
385                 canvas_y2 = canvas_h;
387                 if(edl)
388                 {
389 // Use EDL aspect ratio to shrink one of the canvas dimensions
390                         float out_w = canvas_x2 - canvas_x1;
391                         float out_h = canvas_y2 - canvas_y1;
392                         if(out_w / out_h > edl->get_aspect_ratio())
393                         {
394                                 out_w = (int)(out_h * edl->get_aspect_ratio() + 0.5);
395                                 canvas_x1 = canvas_w / 2 - out_w / 2;
396                         }
397                         else
398                         {
399                                 out_h = (int)(out_w / edl->get_aspect_ratio() + 0.5);
400                                 canvas_y1 = canvas_h / 2 - out_h / 2;
401                         }
402                         canvas_x2 = canvas_x1 + out_w;
403                         canvas_y2 = canvas_y1 + out_h;
405 // Get output frame coords from EDL
406                         output_x1 = 0;
407                         output_y1 = 0;
408                         output_x2 = get_output_w(edl);
409                         output_y2 = get_output_h(edl);
410                 }
411                 else
412 // No EDL to get aspect ratio or output frame coords from
413                 {
414                         output_x1 = 0;
415                         output_y1 = 0;
416                         output_x2 = this->output_w;
417                         output_y2 = this->output_h;
418                 }
419         }
421 // Clamp to minimum value
422         output_x1 = MAX(0, output_x1);
423         output_y1 = MAX(0, output_y1);
424         output_x2 = MAX(output_x1, output_x2);
425         output_y2 = MAX(output_y1, output_y2);
426         canvas_x1 = MAX(0, canvas_x1);
427         canvas_y1 = MAX(0, canvas_y1);
428         canvas_x2 = MAX(canvas_x1, canvas_x2);
429         canvas_y2 = MAX(canvas_y1, canvas_y2);
430 // printf("Canvas::get_transfers 2 %f,%f %f,%f -> %f,%f %f,%f\n",
431 // output_x1,
432 // output_y1,
433 // output_x2,
434 // output_y2,
435 // canvas_x1,
436 // canvas_y1,
437 // canvas_x2,
438 // canvas_y2);
441 int Canvas::scrollbars_exist()
443         return(use_scrollbars && (xscroll || yscroll));
446 int Canvas::get_output_w(EDL *edl)
448         if(use_scrollbars)
449                 return edl->session->output_w;
450         else
451                 return edl->session->output_w;
454 int Canvas::get_output_h(EDL *edl)
456         if(edl)
457         {
458                 if(use_scrollbars)
459                         return edl->session->output_h;
460                 else
461                         return edl->session->output_h;
462         }
467 void Canvas::get_scrollbars(EDL *edl, 
468         int &canvas_x, 
469         int &canvas_y, 
470         int &canvas_w, 
471         int &canvas_h)
473         int need_xscroll = 0;
474         int need_yscroll = 0;
475 //      int done = 0;
476         float zoom_x, zoom_y, conformed_w, conformed_h;
478         if(edl)
479         {
480                 w_needed = edl->session->output_w;
481                 h_needed = edl->session->output_h;
482                 w_visible = w_needed;
483                 h_visible = h_needed;
484         }
485 //printf("Canvas::get_scrollbars 1 %d %d\n", get_xscroll(), get_yscroll());
487         if(use_scrollbars)
488         {
489                 w_needed = edl->session->output_w;
490                 h_needed = edl->session->output_h;
491                 get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
492 //printf("Canvas::get_scrollbars 2 %d %d\n", get_xscroll(), get_yscroll());
494 //              while(!done)
495 //              {
496                         w_visible = (int)(canvas_w / zoom_x);
497                         h_visible = (int)(canvas_h / zoom_y);
498 //                      done = 1;
500 //                      if(w_needed > w_visible)
501                         if(1)
502                         {
503                                 if(!need_xscroll)
504                                 {
505                                         need_xscroll = 1;
506                                         canvas_h -= BC_ScrollBar::get_span(SCROLL_HORIZ);
507 //                                      done = 0;
508                                 }
509                         }
510                         else
511                                 need_xscroll = 0;
513 //                      if(h_needed > h_visible)
514                         if(1)
515                         {
516                                 if(!need_yscroll)
517                                 {
518                                         need_yscroll = 1;
519                                         canvas_w -= BC_ScrollBar::get_span(SCROLL_VERT);
520 //                                      done = 0;
521                                 }
522                         }
523                         else
524                                 need_yscroll = 0;
525 //              }
526 //printf("Canvas::get_scrollbars %d %d %d %d %d %d\n", canvas_w, canvas_h, w_needed, h_needed, w_visible, h_visible);
527 //printf("Canvas::get_scrollbars 3 %d %d\n", get_xscroll(), get_yscroll());
529                 w_visible = (int)(canvas_w / zoom_x);
530                 h_visible = (int)(canvas_h / zoom_y);
531         }
533         if(need_xscroll)
534         {
535                 if(!xscroll)
536                         subwindow->add_subwindow(xscroll = new CanvasXScroll(edl, 
537                                 this, 
538                 canvas_x,
539                 canvas_y + canvas_h,
540                                 w_needed,
541                                 get_xscroll(),
542                                 w_visible,
543                                 canvas_w));
544                 else
545                         xscroll->reposition_window(canvas_x, canvas_y + canvas_h, canvas_w);
547                 if(xscroll->get_length() != w_needed ||
548                         xscroll->get_handlelength() != w_visible)
549                         xscroll->update_length(w_needed, get_xscroll(), w_visible);
550         }
551         else
552         {
553                 if(xscroll) delete xscroll;
554                 xscroll = 0;
555         }
556 //printf("Canvas::get_scrollbars 4 %d %d\n", get_xscroll(), get_yscroll());
558         if(need_yscroll)
559         {
560                 if(!yscroll)
561                         subwindow->add_subwindow(yscroll = new CanvasYScroll(edl, 
562                                 this,
563                 canvas_x + canvas_w,
564                 canvas_y,
565                                 h_needed,
566                                 get_yscroll(),
567                                 h_visible,
568                                 canvas_h));
569                 else
570                         yscroll->reposition_window(canvas_x + canvas_w, canvas_y, canvas_h);
572                 if(yscroll->get_length() != edl->session->output_h ||
573                         yscroll->get_handlelength() != h_visible)
574                         yscroll->update_length(h_needed, get_yscroll(), h_visible);
575         }
576         else
577         {
578                 if(yscroll) delete yscroll;
579                 yscroll = 0;
580         }
581 //printf("Canvas::get_scrollbars 5 %d %d\n", get_xscroll(), get_yscroll());
584 void Canvas::reposition_window(EDL *edl, int x, int y, int w, int h)
586         this->x = x;
587         this->y = y;
588         this->w = w;
589         this->h = h;
590         view_x = x;
591         view_y = y;
592         view_w = w;
593         view_h = h;
594 //printf("Canvas::reposition_window 1\n");
595         get_scrollbars(edl, view_x, view_y, view_w, view_h);
596 //printf("Canvas::reposition_window %d %d %d %d\n", view_x, view_y, view_w, view_h);
597         if(canvas_subwindow)
598         {
599                 canvas_subwindow->reposition_window(view_x, view_y, view_w, view_h);
601 // Need to clear out the garbage in the back
602                 if(canvas_subwindow->get_video_on())
603                 {
604                         canvas_subwindow->set_color(BLACK);
605                         canvas_subwindow->draw_box(0, 
606                                 0, 
607                                 get_canvas()->get_w(), 
608                                 get_canvas()->get_h());
609                         canvas_subwindow->flash();
610                 }
611         }
612         
614         draw_refresh();
615 //printf("Canvas::reposition_window 2\n");
618 void Canvas::set_cursor(int cursor)
620         get_canvas()->set_cursor(cursor);
623 int Canvas::get_cursor_x()
625         return get_canvas()->get_cursor_x();
628 int Canvas::get_cursor_y()
630         return get_canvas()->get_cursor_y();
633 int Canvas::get_buttonpress()
635         return get_canvas()->get_buttonpress();
639 int Canvas::create_objects(EDL *edl)
641         view_x = x;
642         view_y = y;
643         view_w = w;
644         view_h = h;
645         get_scrollbars(edl, view_x, view_y, view_w, view_h);
647         create_canvas();
649         subwindow->add_subwindow(canvas_menu = new CanvasPopup(this));
650         canvas_menu->create_objects();
652         subwindow->add_subwindow(fullscreen_menu = new CanvasFullScreenPopup(this));
653         fullscreen_menu->create_objects();
655         return 0;
658 int Canvas::button_press_event()
660         int result = 0;
662         if(get_canvas()->get_buttonpress() == 3)
663         {
664                 if(get_fullscreen())
665                         fullscreen_menu->activate_menu();
666                 else
667                         canvas_menu->activate_menu();
668                 result = 1;
669         }
671         return result;
674 void Canvas::start_single()
676         is_processing = 1;
677         status_event();
680 void Canvas::stop_single()
682         is_processing = 0;
683         status_event();
686 void Canvas::start_video()
688         if(get_canvas())
689         {
690                 get_canvas()->start_video();
691                 status_event();
692         }
695 void Canvas::stop_video()
697         if(get_canvas())
698         {
699                 get_canvas()->stop_video();
700                 status_event();
701         }
705 void Canvas::start_fullscreen()
707         set_fullscreen(1);
708         create_canvas();
711 void Canvas::stop_fullscreen()
713         set_fullscreen(0);
714         create_canvas();
717 void Canvas::create_canvas()
719         int video_on = 0;
720 SET_TRACE
721         lock_canvas("Canvas::create_canvas");
722 SET_TRACE
725         if(!get_fullscreen())
726         {
727 SET_TRACE
728                 if(canvas_fullscreen)
729                 {
730                         video_on = canvas_fullscreen->get_video_on();
731                         canvas_fullscreen->stop_video();
732                 }
733 SET_TRACE
735                 if(canvas_fullscreen)
736                 {
737                         canvas_fullscreen->hide_window();
738 //                      delete canvas_fullscreen;
739 //                      canvas_fullscreen = 0;
740                 }
741 SET_TRACE
743                 if(!canvas_subwindow)
744                 {
745                         subwindow->add_subwindow(canvas_subwindow = new CanvasOutput(this, 
746                                 view_x, 
747                                 view_y, 
748                                 view_w, 
749                                 view_h));
750                 }
751 SET_TRACE
752         }
753         else
754         {
755                 if(canvas_subwindow)
756                 {
757                         video_on = canvas_subwindow->get_video_on();
758                         canvas_subwindow->stop_video();
760 //                      delete canvas_subwindow;
761 //                      canvas_subwindow = 0;
762                 }
764                 if(!canvas_fullscreen)
765                 {
766                         canvas_fullscreen = new CanvasFullScreen(this,
767                         root_w,
768                         root_h);
769                 }
770                 else
771                 {
772                         canvas_fullscreen->show_window();
773                 }
774         }
775 SET_TRACE
777         if(!video_on) draw_refresh();
778 SET_TRACE
779         if(video_on) get_canvas()->start_video();
780 SET_TRACE
781         unlock_canvas();
786 int Canvas::cursor_leave_event_base(BC_WindowBase *caller)
788         int result = 0;
789         if(cursor_inside) result = cursor_leave_event();
790         cursor_inside = 0;
791         return result;
794 int Canvas::cursor_enter_event_base(BC_WindowBase *caller)
796         int result = 0;
797         if(caller->is_event_win() && caller->cursor_inside())
798         {
799                 cursor_inside = 1;
800                 result = cursor_enter_event();
801         }
802         return result;
805 int Canvas::button_press_event_base(BC_WindowBase *caller)
807         if(caller->is_event_win() && caller->cursor_inside())
808         {
809                 return button_press_event();
810         }
811         return 0;
814 int Canvas::keypress_event(BC_WindowBase *caller)
816         int caller_is_canvas = (caller == get_canvas());
817         if(caller->get_keypress() == 'f')
818         {
819                 caller->unlock_window();
820                 if(get_fullscreen())
821                         stop_fullscreen();
822                 else
823                         start_fullscreen();
824                 if(!caller_is_canvas) caller->lock_window("Canvas::keypress_event 1");
825                 return 1;
826         }
827         else
828         if(caller->get_keypress() == ESC)
829         {
830                 caller->unlock_window();
831                 if(get_fullscreen())
832                         stop_fullscreen();
833                 if(!caller_is_canvas) caller->lock_window("Canvas::keypress_event 2");
834                 return 1;
835         }
836         return 0;
855 CanvasOutput::CanvasOutput(Canvas *canvas,
856     int x,
857     int y,
858     int w,
859     int h)
860  : BC_SubWindow(x, y, w, h, BLACK)
862         this->canvas = canvas;
865 CanvasOutput::~CanvasOutput()
869 int CanvasOutput::cursor_leave_event()
871         return canvas->cursor_leave_event_base(this);
874 int CanvasOutput::cursor_enter_event()
876         return canvas->cursor_enter_event_base(this);
879 int CanvasOutput::button_press_event()
881         return canvas->button_press_event_base(this);
884 int CanvasOutput::button_release_event()
886         return canvas->button_release_event();
889 int CanvasOutput::cursor_motion_event()
891         return canvas->cursor_motion_event();
894 int CanvasOutput::keypress_event()
896         return canvas->keypress_event(this);
911 CanvasFullScreen::CanvasFullScreen(Canvas *canvas,
912     int w,
913     int h)
914  : BC_FullScreen(canvas->subwindow, 
915         w, 
916         h, 
917         BLACK,
918         0,
919         0,
920         0)
922         this->canvas = canvas;
925 CanvasFullScreen::~CanvasFullScreen()
941 CanvasXScroll::CanvasXScroll(EDL *edl, 
942         Canvas *canvas, 
943     int x, 
944     int y, 
945         int length, 
946         int position, 
947         int handle_length,
948     int pixels)
949  : BC_ScrollBar(x, 
950                 y, 
951                 SCROLL_HORIZ, 
952                 pixels, 
953                 length, 
954                 position, 
955                 handle_length)
957         this->canvas = canvas;
960 CanvasXScroll::~CanvasXScroll()
964 int CanvasXScroll::handle_event()
966 //printf("CanvasXScroll::handle_event %d %d %d\n", get_length(), get_value(), get_handlelength());
967         canvas->update_zoom(get_value(), canvas->get_yscroll(), canvas->get_zoom());
968         canvas->draw_refresh();
969         return 1;
977 CanvasYScroll::CanvasYScroll(EDL *edl, 
978         Canvas *canvas, 
979     int x, 
980     int y, 
981         int length, 
982         int position, 
983         int handle_length,
984     int pixels)
985  : BC_ScrollBar(x, 
986                 y, 
987                 SCROLL_VERT, 
988                 pixels, 
989                 length, 
990                 position, 
991                 handle_length)
993         this->canvas = canvas;
996 CanvasYScroll::~CanvasYScroll()
1000 int CanvasYScroll::handle_event()
1002 //printf("CanvasYScroll::handle_event %d %d\n", get_value(), get_length());
1003         canvas->update_zoom(canvas->get_xscroll(), get_value(), canvas->get_zoom());
1004         canvas->draw_refresh();
1005         return 1;
1013 CanvasFullScreenPopup::CanvasFullScreenPopup(Canvas *canvas)
1014  : BC_PopupMenu(0, 
1015                 0, 
1016                 0, 
1017                 "", 
1018                 0)
1020         this->canvas = canvas;
1024 void CanvasFullScreenPopup::create_objects()
1026         if(canvas->use_cwindow) add_item(new CanvasPopupAuto(canvas));
1027         add_item(new CanvasSubWindowItem(canvas));
1031 CanvasSubWindowItem::CanvasSubWindowItem(Canvas *canvas)
1032  : BC_MenuItem(_("Windowed"), "f", 'f')
1034         this->canvas = canvas;
1037 int CanvasSubWindowItem::handle_event()
1039 // It isn't a problem to delete the canvas from in here because the event
1040 // dispatcher is the canvas subwindow.
1041         canvas->subwindow->unlock_window();
1042         canvas->stop_fullscreen();
1043         canvas->subwindow->lock_window("CanvasSubWindowItem::handle_event");
1044         return 1;
1054 CanvasPopup::CanvasPopup(Canvas *canvas)
1055  : BC_PopupMenu(0, 
1056                 0, 
1057                 0, 
1058                 "", 
1059                 0)
1061         this->canvas = canvas;
1064 CanvasPopup::~CanvasPopup()
1068 void CanvasPopup::create_objects()
1070         add_item(new CanvasPopupSize(canvas, _("Zoom 25%"), 0.25));
1071         add_item(new CanvasPopupSize(canvas, _("Zoom 33%"), 0.33));
1072         add_item(new CanvasPopupSize(canvas, _("Zoom 50%"), 0.5));
1073         add_item(new CanvasPopupSize(canvas, _("Zoom 75%"), 0.75));
1074         add_item(new CanvasPopupSize(canvas, _("Zoom 100%"), 1.0));
1075         add_item(new CanvasPopupSize(canvas, _("Zoom 150%"), 1.5));
1076         add_item(new CanvasPopupSize(canvas, _("Zoom 200%"), 2.0));
1077         add_item(new CanvasPopupSize(canvas, _("Zoom 300%"), 3.0));
1078         add_item(new CanvasPopupSize(canvas, _("Zoom 400%"), 4.0));
1079         if(canvas->use_cwindow)
1080         {
1081                 add_item(new CanvasPopupAuto(canvas));
1082                 add_item(new CanvasPopupResetCamera(canvas));
1083                 add_item(new CanvasPopupResetProjector(canvas));
1084                 add_item(toggle_controls = new CanvasToggleControls(canvas));
1085         }
1086         if(canvas->use_rwindow)
1087         {
1088                 add_item(new CanvasPopupResetTranslation(canvas));
1089         }
1090         if(canvas->use_vwindow)
1091         {
1092                 add_item(new CanvasPopupRemoveSource(canvas));
1093         }
1094         add_item(new CanvasFullScreenItem(canvas));
1099 CanvasPopupAuto::CanvasPopupAuto(Canvas *canvas)
1100  : BC_MenuItem(_("Zoom Auto"))
1102         this->canvas = canvas;
1105 int CanvasPopupAuto::handle_event()
1107         canvas->zoom_auto();
1108         return 1;
1112 CanvasPopupSize::CanvasPopupSize(Canvas *canvas, char *text, float percentage)
1113  : BC_MenuItem(text)
1115         this->canvas = canvas;
1116         this->percentage = percentage;
1118 CanvasPopupSize::~CanvasPopupSize()
1121 int CanvasPopupSize::handle_event()
1123         canvas->zoom_resize_window(percentage);
1124         return 1;
1129 CanvasPopupResetCamera::CanvasPopupResetCamera(Canvas *canvas)
1130  : BC_MenuItem(_("Reset camera"))
1132         this->canvas = canvas;
1134 int CanvasPopupResetCamera::handle_event()
1136         canvas->reset_camera();
1137         return 1;
1142 CanvasPopupResetProjector::CanvasPopupResetProjector(Canvas *canvas)
1143  : BC_MenuItem(_("Reset projector"))
1145         this->canvas = canvas;
1147 int CanvasPopupResetProjector::handle_event()
1149         canvas->reset_projector();
1150         return 1;
1155 CanvasPopupResetTranslation::CanvasPopupResetTranslation(Canvas *canvas)
1156  : BC_MenuItem(_("Reset translation"))
1158         this->canvas = canvas;
1160 int CanvasPopupResetTranslation::handle_event()
1162         canvas->reset_translation();
1163         return 1;
1168 CanvasToggleControls::CanvasToggleControls(Canvas *canvas)
1169  : BC_MenuItem(calculate_text(canvas->get_cwindow_controls()))
1171         this->canvas = canvas;
1173 int CanvasToggleControls::handle_event()
1175         canvas->toggle_controls();
1176         set_text(calculate_text(canvas->get_cwindow_controls()));
1177         return 1;
1180 char* CanvasToggleControls::calculate_text(int cwindow_controls)
1182         if(!cwindow_controls) 
1183                 return _("Show controls");
1184         else
1185                 return _("Hide controls");
1194 CanvasFullScreenItem::CanvasFullScreenItem(Canvas *canvas)
1195  : BC_MenuItem(_("Fullscreen"), "f", 'f')
1197         this->canvas = canvas;
1199 int CanvasFullScreenItem::handle_event()
1201         canvas->subwindow->unlock_window();
1202         canvas->start_fullscreen();
1203         canvas->subwindow->lock_window("CanvasFullScreenItem::handle_event");
1204         return 1;
1215 CanvasPopupRemoveSource::CanvasPopupRemoveSource(Canvas *canvas)
1216  : BC_MenuItem(_("Close source"))
1218         this->canvas = canvas;
1220 int CanvasPopupRemoveSource::handle_event()
1222         canvas->close_source();
1223         return 1;