4 * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "bcsignals.h"
26 #include "edlsession.h"
29 #include "mainsession.h"
30 #include "mwindowgui.h"
33 #include "playback3d.h"
34 #include "videodevice.h"
39 Canvas::Canvas(MWindow *mwindow, BC_WindowBase *subwindow,
40 int x, int y, int w, int h, int output_w, int output_h,
45 int xs10 = xS(10), ys10 = yS(10);
46 if(w < xs10) w = xs10;
47 if(h < ys10) h = ys10;
48 this->mwindow = mwindow;
49 this->subwindow = subwindow;
54 this->output_w = output_w;
55 this->output_h = output_h;
56 this->use_scrollbars = use_scrollbars;
57 this->canvas_auxwindow = 0;
58 this->scr_w0 = subwindow->get_screen_w(0, 0);
59 this->root_w = subwindow->get_root_w(0);
60 this->root_h = subwindow->get_root_h(0);
61 canvas_lock = new Condition(1, "Canvas::canvas_lock", 1);
66 if(refresh_frame) delete refresh_frame;
68 if(yscroll) delete yscroll;
69 if(xscroll) delete xscroll;
70 delete canvas_subwindow;
71 delete canvas_fullscreen;
84 canvas_fullscreen = 0;
90 BC_WindowBase *Canvas::lock_canvas(const char *loc)
92 canvas_lock->lock(loc);
93 BC_WindowBase *wdw = get_canvas();
94 if( wdw ) wdw->lock_window(loc);
98 void Canvas::unlock_canvas()
100 BC_WindowBase *wdw = get_canvas();
101 if( wdw ) wdw->unlock_window();
102 canvas_lock->unlock();
105 BC_WindowBase* Canvas::get_canvas()
107 if(get_fullscreen() && canvas_fullscreen)
108 return canvas_fullscreen;
109 return canvas_auxwindow ? canvas_auxwindow : canvas_subwindow;
112 void Canvas::use_auxwindow(BC_WindowBase *aux)
114 canvas_auxwindow = aux;
117 void Canvas::use_cwindow()
119 canvas_menu->use_cwindow();
120 fullscreen_menu->use_cwindow();
123 void Canvas::use_rwindow()
125 canvas_menu->use_rwindow();
128 void Canvas::use_vwindow()
130 canvas_menu->use_vwindow();
133 int Canvas::get_fullscreen()
135 return is_fullscreen;
138 void Canvas::set_fullscreen(int value)
140 is_fullscreen = value;
143 // Get dimensions given a zoom
144 void Canvas::calculate_sizes(float aspect_ratio,
145 int output_w, int output_h, float zoom,
148 // Horizontal stretch
149 if( (float)output_w/output_h <= aspect_ratio ) {
150 w = (float)output_h * aspect_ratio * zoom;
151 h = (float)output_h * zoom;
155 h = (float)output_w / aspect_ratio * zoom;
156 w = (float)output_w * zoom;
160 float Canvas::get_x_offset(EDL *edl, int single_channel,
161 float zoom_x, float conformed_w, float conformed_h)
163 if( use_scrollbars ) return get_xscroll();
164 int canvas_w = get_canvas()->get_w(), out_w = canvas_w;
165 int canvas_h = get_canvas()->get_h(), out_h = canvas_h;
166 float conformed_ratio = conformed_w/conformed_h;
167 if( (float)out_w/out_h > conformed_ratio )
168 out_w = out_h * conformed_ratio + 0.5;
169 float ret = out_w >= canvas_w ? 0 : -0.5f*(canvas_w - out_w) / zoom_x;
173 float Canvas::get_y_offset(EDL *edl, int single_channel,
174 float zoom_y, float conformed_w, float conformed_h)
176 if( use_scrollbars ) return get_yscroll();
177 int canvas_w = get_canvas()->get_w(), out_w = canvas_w;
178 int canvas_h = get_canvas()->get_h(), out_h = canvas_h;
179 float conformed_ratio = conformed_w/conformed_h;
180 if( (float)out_w/out_h <= conformed_ratio )
181 out_h = out_w / conformed_ratio + 0.5f;
182 float ret = out_h >= canvas_h ? 0 : -0.5f*(canvas_h - out_h) / zoom_y;
186 // This may not be used anymore
187 void Canvas::check_boundaries(EDL *edl, int &x, int &y, float &zoom)
189 if(x + w_visible > w_needed) x = w_needed - w_visible;
190 if(y + h_visible > h_needed) y = h_needed - h_visible;
196 void Canvas::update_scrollbars(EDL *edl, int flush)
200 if( use_scrollbars ) {
201 if( xscroll ) xscroll->update_length(w_needed, get_xscroll(), w_visible, flush);
202 if( yscroll ) yscroll->update_length(h_needed, get_yscroll(), h_visible, flush);
206 float Canvas::get_auto_zoom(EDL *edl)
208 float conformed_w, conformed_h;
209 edl->calculate_conformed_dimensions(0, conformed_w, conformed_h);
210 BC_WindowBase *window = get_canvas();
211 int window_w = window ? window->get_w() : w;
212 int window_h = window ? window->get_h() : h;
213 float zoom_x = window_w / conformed_w;
214 float zoom_y = window_h / conformed_h;
215 return zoom_x < zoom_y ? zoom_x : zoom_y;
217 void Canvas::zoom_auto()
222 void Canvas::get_zooms(EDL *edl, int single_channel,
223 float &zoom_x, float &zoom_y,
224 float &conformed_w, float &conformed_h)
226 edl->calculate_conformed_dimensions(single_channel,
227 conformed_w, conformed_h);
229 float zoom = get_zoom();
230 if( !use_scrollbars || !zoom ) zoom = get_auto_zoom(edl);
231 zoom_x = zoom * conformed_w / get_output_w(edl);
232 zoom_y = zoom * conformed_h / get_output_h(edl);
235 void Canvas::set_zoom(EDL *edl, float zoom)
237 BC_WindowBase *window = get_canvas();
238 int cw = window ? window->get_w() : w;
239 int ch = window ? window->get_h() : h;
240 float cx = 0.5f * cw, cy = 0.5f * ch;
241 set_zoom(edl, zoom, cx, cy);
244 void Canvas::set_zoom(EDL *edl, float zoom, float cx, float cy)
246 float output_x = cx, output_y = cy;
247 canvas_to_output(edl, 0, output_x, output_y);
248 update_zoom(0, 0, zoom);
249 float zoom_x, zoom_y, conformed_w, conformed_h;
250 get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
252 output_x -= cx / zoom_x;
253 output_y -= cy / zoom_y;
256 output_x = get_x_offset(edl, 0, zoom_x, conformed_w, conformed_h);
257 output_y = get_y_offset(edl, 0, zoom_y, conformed_w, conformed_h);
259 update_zoom(output_x, output_y, zoom);
263 // Convert a coordinate on the canvas to a coordinate on the output
264 void Canvas::canvas_to_output(EDL *edl, int single_channel, float &x, float &y)
266 float zoom_x, zoom_y, conformed_w, conformed_h;
267 get_zooms(edl, single_channel, zoom_x, zoom_y, conformed_w, conformed_h);
269 //printf("Canvas::canvas_to_output y=%f zoom_y=%f y_offset=%f\n",
270 // y, zoom_y, get_y_offset(edl, single_channel, zoom_y, conformed_w, conformed_h));
272 x = (float)x / zoom_x + get_x_offset(edl, single_channel, zoom_x, conformed_w, conformed_h);
273 y = (float)y / zoom_y + get_y_offset(edl, single_channel, zoom_y, conformed_w, conformed_h);
276 void Canvas::output_to_canvas(EDL *edl, int single_channel, float &x, float &y)
278 float zoom_x, zoom_y, conformed_w, conformed_h;
279 get_zooms(edl, single_channel, zoom_x, zoom_y, conformed_w, conformed_h);
281 //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));
283 x = (float)zoom_x * (x - get_x_offset(edl, single_channel, zoom_x, conformed_w, conformed_h));
284 y = (float)zoom_y * (y - get_y_offset(edl, single_channel, zoom_y, conformed_w, conformed_h));
289 void Canvas::get_transfers(EDL *edl,
290 float &output_x1, float &output_y1, float &output_x2, float &output_y2,
291 float &canvas_x1, float &canvas_y1, float &canvas_x2, float &canvas_y2,
292 int canvas_w, int canvas_h)
294 //printf("Canvas::get_transfers %d canvas_w=%d canvas_h=%d\n",
295 // __LINE__, canvas_w, canvas_h);
296 // automatic canvas size detection
297 if( canvas_w < 0 ) canvas_w = get_canvas()->get_w();
298 if( canvas_h < 0 ) canvas_h = get_canvas()->get_h();
300 float in_x1, in_y1, in_x2, in_y2;
301 float out_x1, out_y1, out_x2, out_y2;
302 float zoom_x, zoom_y, conformed_w, conformed_h;
304 get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
305 out_x1 = 0; out_x2 = canvas_w;
306 out_y1 = 0; out_y2 = canvas_h;
307 in_x1 = 0; in_x2 = canvas_w;
308 in_y1 = 0; in_y2 = canvas_h;
309 canvas_to_output(edl, 0, in_x1, in_y1);
310 canvas_to_output(edl, 0, in_x2, in_y2);
313 out_x1 += -in_x1 * zoom_x;
318 out_y1 += -in_y1 * zoom_y;
322 int output_w = get_output_w(edl);
323 int output_h = get_output_h(edl);
324 if( in_x2 > output_w ) {
325 out_x2 -= (in_x2 - output_w) * zoom_x;
329 if( in_y2 > output_h ) {
330 out_y2 -= (in_y2 - output_h) * zoom_y;
334 output_x1 = in_x1; output_x2 = in_x2;
335 output_y1 = in_y1; output_y2 = in_y2;
336 canvas_x1 = out_x1; canvas_x2 = out_x2;
337 canvas_y1 = out_y1; canvas_y2 = out_y2;
339 // Clamp to minimum value
340 if( output_x1 < 0 ) output_x1 = 0;
341 if( output_x2 < output_x1 ) output_x2 = output_x1;
342 if( canvas_x1 < 0 ) canvas_x1 = 0;
343 if( canvas_x2 < canvas_x1 ) canvas_x2 = canvas_x1;
344 // printf("Canvas::get_transfers %d %f,%f %f,%f -> %f,%f %f,%f\n", __LINE__,
345 // output_x1, output_y1, output_x2, output_y2,
346 // canvas_x1, canvas_y1, canvas_x2, canvas_y2);
349 int Canvas::scrollbars_exist()
351 return use_scrollbars && (xscroll || yscroll);
354 int Canvas::get_output_w(EDL *edl)
356 return edl->session->output_w;
359 int Canvas::get_output_h(EDL *edl)
361 return edl->session->output_h;
365 int Canvas::get_scrollbars(EDL *edl)
368 BC_WindowBase *window = get_canvas();
369 if( !window ) use_scrollbars = 0;
370 int canvas_w = w, canvas_h = h;
372 w_needed = w_visible = edl ? edl->session->output_w : view_w;
373 h_needed = h_visible = edl ? edl->session->output_h : view_h;
375 int need_xscroll = 0, need_yscroll = 0;
376 if( edl && use_scrollbars ) {
377 float zoom_x, zoom_y, conformed_w, conformed_h;
378 get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
379 w_visible = canvas_w / zoom_x;
380 h_visible = canvas_h / zoom_y;
381 float output_x = 0, output_y = 0;
382 output_to_canvas(edl, 0, output_x, output_y);
383 if( output_x < 0 ) need_xscroll = 1;
384 if( output_y < 0 ) need_yscroll = 1;
385 output_x = w_needed, output_y = h_needed;
386 output_to_canvas(edl, 0, output_x, output_y);
387 if( output_x > canvas_w ) need_xscroll = 1;
388 if( output_y > canvas_h ) need_yscroll = 1;
390 canvas_h -= BC_ScrollBar::get_span(SCROLL_HORIZ);
391 h_visible = canvas_h / zoom_y;
394 canvas_w -= BC_ScrollBar::get_span(SCROLL_VERT);
395 w_visible = canvas_w / zoom_x;
403 xscroll = new CanvasXScroll(edl, this, view_x, view_y + view_h,
404 w_needed, get_xscroll(), w_visible, view_w);
405 subwindow->add_subwindow(xscroll);
406 xscroll->show_window(0);
409 xscroll->reposition_window(view_x, view_y + view_h, view_w);
411 if( xscroll->get_length() != w_needed ||
412 xscroll->get_handlelength() != w_visible )
413 xscroll->update_length(w_needed, get_xscroll(), w_visible, 0);
417 delete xscroll; xscroll = 0;
423 yscroll = new CanvasYScroll(edl, this, view_x + view_w, view_y,
424 h_needed, get_yscroll(), h_visible, view_h);
425 subwindow->add_subwindow(yscroll);
426 yscroll->show_window(0);
429 yscroll->reposition_window(view_x + view_w, view_y, view_h);
431 if( yscroll->get_length() != edl->session->output_h ||
432 yscroll->get_handlelength() != h_visible )
433 yscroll->update_length(h_needed, get_yscroll(), h_visible, 0);
437 delete yscroll; yscroll = 0;
444 void Canvas::update_geometry(EDL *edl, int x, int y, int w, int h)
447 if( this->x != x || this->y != y ||
448 this->w != w || this->h != h )
451 redraw = get_scrollbars(edl);
453 reposition_window(edl, x, y, w, h);
456 void Canvas::reposition_window(EDL *edl, int x, int y, int w, int h)
458 this->x = view_x = x; this->y = view_y = y;
459 this->w = view_w = w; this->h = view_h = h;
460 //printf("Canvas::reposition_window 1\n");
462 //printf("Canvas::reposition_window %d %d %d %d\n", view_x, view_y, view_w, view_h);
463 if( canvas_subwindow ) {
464 canvas_subwindow->reposition_window(view_x, view_y, view_w, view_h);
466 // Need to clear out the garbage in the back
467 if( canvas_subwindow->get_video_on() )
473 // must hold window lock
474 int Canvas::refresh(int flush)
476 BC_WindowBase *window = get_canvas();
477 if( !window ) return 0;
478 // relock in lock order to prevent deadlock
479 window->unlock_window();
480 lock_canvas("Canvas::refresh");
482 canvas_lock->unlock();
485 // must not hold locks
486 int Canvas::redraw(int flush)
488 lock_canvas("Canvas::redraw");
494 void Canvas::set_cursor(int cursor)
496 get_canvas()->set_cursor(cursor, 0, 1);
499 int Canvas::get_cursor_x()
501 return get_canvas()->get_cursor_x();
504 int Canvas::get_cursor_y()
506 return get_canvas()->get_cursor_y();
509 int Canvas::get_buttonpress()
511 return get_canvas()->get_buttonpress();
515 void Canvas::create_objects(EDL *edl)
517 view_x = x; view_y = y;
518 view_w = w; view_h = h;
521 subwindow->unlock_window();
523 subwindow->lock_window("Canvas::create_objects");
525 subwindow->add_subwindow(canvas_menu = new CanvasPopup(this));
526 canvas_menu->create_objects();
528 subwindow->add_subwindow(fullscreen_menu = new CanvasFullScreenPopup(this));
529 fullscreen_menu->create_objects();
533 int Canvas::button_press_event()
537 if(get_canvas()->get_buttonpress() == 3)
540 fullscreen_menu->activate_menu();
542 canvas_menu->activate_menu();
549 void Canvas::start_single()
555 void Canvas::stop_single()
561 void Canvas::start_video()
565 get_canvas()->start_video();
570 void Canvas::stop_video()
574 get_canvas()->stop_video();
580 int Canvas::use_fullscreen(int on)
582 if( on && !get_fullscreen() ) {
586 if( !on && get_fullscreen() ) {
593 void Canvas::start_fullscreen()
599 void Canvas::stop_fullscreen()
605 void Canvas::create_canvas()
607 canvas_lock->lock("Canvas::create_canvas");
609 BC_WindowBase *wdw = 0;
610 if( !get_fullscreen() ) {
612 if( canvas_fullscreen ) {
613 canvas_fullscreen->lock_window("Canvas::create_canvas 1");
614 video_on = canvas_fullscreen->get_video_on();
615 if( video_on ) canvas_fullscreen->stop_video();
616 canvas_fullscreen->hide_window();
617 canvas_fullscreen->unlock_window();
619 if( !canvas_auxwindow && !canvas_subwindow ) {
620 subwindow->add_subwindow(canvas_subwindow = new CanvasOutput(this,
621 view_x, view_y, view_w, view_h));
624 wdw->lock_window("Canvas::create_canvas 2");
628 wdw = canvas_auxwindow ? canvas_auxwindow : canvas_subwindow;
629 wdw->lock_window("Canvas::create_canvas 3");
630 video_on = wdw->get_video_on();
631 if( video_on ) wdw->stop_video();
633 wdw->get_fullscreen_geometry(x, y, w, h);
634 wdw->unlock_window();
635 if( canvas_fullscreen ) {
636 if( x != canvas_fullscreen->get_x() ||
637 y != canvas_fullscreen->get_y() ||
638 w != canvas_fullscreen->get_w() ||
639 h != canvas_fullscreen->get_h() ) {
640 delete canvas_fullscreen;
641 canvas_fullscreen = 0;
644 if( !canvas_fullscreen )
645 canvas_fullscreen = new CanvasFullScreen(this, w, h);
646 wdw = canvas_fullscreen;
647 wdw->lock_window("Canvas::create_canvas 4");
650 wdw->reposition_window(x, y);
659 wdw->unlock_window();
660 canvas_lock->unlock();
665 int Canvas::cursor_leave_event_base(BC_WindowBase *caller)
668 if(cursor_inside) result = cursor_leave_event();
673 int Canvas::cursor_enter_event_base(BC_WindowBase *caller)
676 if(caller->is_event_win() && caller->cursor_inside())
679 result = cursor_enter_event();
684 int Canvas::button_press_event_base(BC_WindowBase *caller)
686 if(caller->is_event_win() && caller->cursor_inside())
688 return button_press_event();
693 int Canvas::keypress_event(BC_WindowBase *caller)
695 int key = caller->get_keypress();
698 caller->unlock_window();
699 use_fullscreen(get_fullscreen() ? 0 : 1);
700 caller->lock_window("Canvas::keypress_event 1");
703 caller->unlock_window();
705 caller->lock_window("Canvas::keypress_event 2");
713 void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame)
715 int best_color_model = output_frame->get_color_model();
717 device->out_config->driver == PLAYBACK_X11_GL &&
718 output_frame->get_opengl_state() != VFrame::RAM;
720 // OpenGL does YUV->RGB in the compositing step
722 best_color_model = BC_RGB888;
723 else if( BC_CModels::has_alpha(best_color_model) ) {
725 BC_CModels::is_float(best_color_model ) ?
727 BC_CModels::is_yuv(best_color_model ) ?
728 ( BC_CModels::calculate_pixelsize(best_color_model) > 8 ?
729 BC_YUV161616 : BC_YUV888 ) :
730 ( BC_CModels::calculate_pixelsize(best_color_model) > 8 ?
731 BC_RGB161616 : BC_RGB888 ) ;
733 int out_w = output_frame->get_w();
734 int out_h = output_frame->get_h();
736 (refresh_frame->get_w() != out_w ||
737 refresh_frame->get_h() != out_h ||
738 refresh_frame->get_color_model() != best_color_model ) ) {
739 // x11 direct render uses BC_BGR8888, use tranfer_from to remap
740 delete refresh_frame; refresh_frame = 0;
743 if( !refresh_frame ) {
745 new VFrame(out_w, out_h, best_color_model);
750 mwindow->playback_3d->copy_from(this, refresh_frame, output_frame, 0);
751 lock_canvas("Canvas::update_refresh");
754 refresh_frame->transfer_from(output_frame, -1);
757 void Canvas::clear(int flash)
759 BC_WindowBase *window = get_canvas();
760 if( !window ) return;
761 window->set_bg_color(get_clear_color());
762 window->clear_box(0,0, window->get_w(), window->get_h());
763 if( flash ) window->flash();
766 void Canvas::clear_borders(EDL *edl)
768 BC_WindowBase *window = get_canvas();
769 if( !window ) return;
771 int window_w = window->get_w();
772 int window_h = window->get_h();
773 float output_x1,output_y1, output_x2,output_y2;
774 float canvas_x1,canvas_y1, canvas_x2,canvas_y2;
776 output_x1, output_y1, output_x2, output_y2,
777 canvas_x1, canvas_y1, canvas_x2, canvas_y2);
778 int color = get_clear_color();
779 window->set_color(color);
781 if( canvas_y1 > 0 ) {
782 window->draw_box(0, 0, window_w, canvas_y1);
783 window->flash(0, 0, window_w, canvas_y1);
786 if( canvas_y2 < window_h ) {
787 window->draw_box(0, canvas_y2, window_w, window_h-canvas_y2);
788 window->flash(0, canvas_y2, window_w, window_h-canvas_y2);
791 if( canvas_x1 > 0 ) {
792 window->draw_box(0, canvas_y1, canvas_x1, canvas_y2-canvas_y1);
793 window->flash(0, canvas_y1, canvas_x1, canvas_y2-canvas_y1);
796 if( canvas_x2 < window_w ) {
797 window->draw_box(canvas_x2, canvas_y1,
798 window_w-canvas_x2, canvas_y2-canvas_y1);
799 window->flash(canvas_x2, canvas_y1,
800 window_w-canvas_x2, canvas_y2-canvas_y1);
804 int Canvas::get_clear_color()
806 BC_WindowBase *cwdw = get_canvas();
807 if( !cwdw ) return 0;
808 return cwdw->get_bg_color();
811 CanvasOutput::CanvasOutput(Canvas *canvas,
812 int x, int y, int w, int h)
813 : BC_SubWindow(x, y, w, h, canvas->get_clear_color())
815 this->canvas = canvas;
818 CanvasOutput::~CanvasOutput()
822 int CanvasOutput::cursor_leave_event()
824 return canvas->cursor_leave_event_base(canvas->get_canvas());
827 int CanvasOutput::cursor_enter_event()
829 return canvas->cursor_enter_event_base(canvas->get_canvas());
832 int CanvasOutput::button_press_event()
834 return canvas->button_press_event_base(canvas->get_canvas());
837 int CanvasOutput::button_release_event()
839 return canvas->button_release_event();
842 int CanvasOutput::cursor_motion_event()
844 return canvas->cursor_motion_event();
847 int CanvasOutput::keypress_event()
849 return canvas->keypress_event(canvas->get_canvas());
854 CanvasFullScreen::CanvasFullScreen(Canvas *canvas, int w, int h)
855 : BC_FullScreen(canvas->subwindow, w, h, canvas->get_clear_color(), 0, 0, 0)
857 this->canvas = canvas;
860 CanvasFullScreen::~CanvasFullScreen()
865 CanvasXScroll::CanvasXScroll(EDL *edl, Canvas *canvas, int x, int y,
866 int length, int position, int handle_length, int pixels)
867 : BC_ScrollBar(x, y, SCROLL_HORIZ, pixels, length, position, handle_length)
869 this->canvas = canvas;
872 CanvasXScroll::~CanvasXScroll()
876 int CanvasXScroll::handle_event()
878 canvas->update_zoom(get_value(), canvas->get_yscroll(),
880 return canvas->refresh(1);
884 CanvasYScroll::CanvasYScroll(EDL *edl, Canvas *canvas, int x, int y,
885 int length, int position, int handle_length, int pixels)
886 : BC_ScrollBar(x, y, SCROLL_VERT, pixels, length, position, handle_length)
888 this->canvas = canvas;
891 CanvasYScroll::~CanvasYScroll()
895 int CanvasYScroll::handle_event()
897 canvas->update_zoom(canvas->get_xscroll(), get_value(),
899 return canvas->refresh(1);
903 CanvasFullScreenPopup::CanvasFullScreenPopup(Canvas *canvas)
904 : BC_PopupMenu(0, 0, 0, "", 0)
906 this->canvas = canvas;
910 void CanvasFullScreenPopup::create_objects()
912 add_item(new CanvasSubWindowItem(canvas));
915 void CanvasFullScreenPopup::use_cwindow()
917 add_item(new CanvasPopupAuto(canvas));
920 CanvasSubWindowItem::CanvasSubWindowItem(Canvas *canvas)
921 : BC_MenuItem(_("Windowed"), "f", 'f')
923 this->canvas = canvas;
926 int CanvasSubWindowItem::handle_event()
928 // It isn't a problem to delete the canvas from in here because the event
929 // dispatcher is the canvas subwindow.
930 canvas->subwindow->unlock_window();
931 canvas->use_fullscreen(0);
932 canvas->subwindow->lock_window("CanvasSubWindowItem::handle_event");
937 CanvasPopup::CanvasPopup(Canvas *canvas)
938 : BC_PopupMenu(0, 0, 0, "", 0)
940 this->canvas = canvas;
943 CanvasPopup::~CanvasPopup()
947 CanvasZoomSize::CanvasZoomSize(Canvas *canvas)
948 : BC_MenuItem(_("Zoom..."))
950 this->canvas = canvas;
953 CanvasSizeSubMenu::CanvasSizeSubMenu(CanvasZoomSize *zoom_size)
955 this->zoom_size = zoom_size;
958 void CanvasPopup::create_objects()
960 add_item(new BC_MenuItem("-"));
961 add_item(new CanvasFullScreenItem(canvas));
963 CanvasZoomSize *zoom_size = new CanvasZoomSize(canvas);
965 CanvasSizeSubMenu *submenu = new CanvasSizeSubMenu(zoom_size);
966 zoom_size->add_submenu(submenu);
968 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 25%"), 0.25));
969 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 33%"), 0.33));
970 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 50%"), 0.5));
971 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 75%"), 0.75));
972 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 100%"), 1.0));
973 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 150%"), 1.5));
974 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 200%"), 2.0));
975 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 300%"), 3.0));
976 submenu->add_submenuitem(new CanvasPopupSize(canvas, _("Zoom 400%"), 4.0));
979 void CanvasPopup::use_cwindow()
981 add_item(new CanvasPopupAuto(canvas));
982 add_item(new CanvasPopupResetCamera(canvas));
983 add_item(new CanvasPopupResetProjector(canvas));
984 add_item(new CanvasPopupCameraKeyframe(canvas));
985 add_item(new CanvasPopupProjectorKeyframe(canvas));
986 add_item(toggle_controls = new CanvasToggleControls(canvas));
989 void CanvasPopup::use_rwindow()
991 add_item(new CanvasPopupResetTranslation(canvas));
994 void CanvasPopup::use_vwindow()
996 add_item(new CanvasPopupRemoveSource(canvas));
1000 CanvasPopupAuto::CanvasPopupAuto(Canvas *canvas)
1001 : BC_MenuItem(_("Zoom Auto"))
1003 this->canvas = canvas;
1006 int CanvasPopupAuto::handle_event()
1008 canvas->zoom_auto();
1013 CanvasPopupSize::CanvasPopupSize(Canvas *canvas, char *text, float percentage)
1016 this->canvas = canvas;
1017 this->percentage = percentage;
1019 CanvasPopupSize::~CanvasPopupSize()
1022 int CanvasPopupSize::handle_event()
1024 canvas->zoom_resize_window(percentage);
1029 CanvasPopupResetCamera::CanvasPopupResetCamera(Canvas *canvas)
1030 : BC_MenuItem(_("Reset camera"), _("F11"), KEY_F11)
1032 this->canvas = canvas;
1034 int CanvasPopupResetCamera::handle_event()
1036 canvas->reset_camera();
1040 CanvasPopupResetProjector::CanvasPopupResetProjector(Canvas *canvas)
1041 : BC_MenuItem(_("Reset projector"), _("F12"), KEY_F12)
1043 this->canvas = canvas;
1045 int CanvasPopupResetProjector::handle_event()
1047 canvas->reset_projector();
1052 CanvasPopupCameraKeyframe::CanvasPopupCameraKeyframe(Canvas *canvas)
1053 : BC_MenuItem(_("Camera keyframe"), _("Shift-F11"), KEY_F11)
1055 this->canvas = canvas;
1058 int CanvasPopupCameraKeyframe::handle_event()
1060 canvas->camera_keyframe();
1064 CanvasPopupProjectorKeyframe::CanvasPopupProjectorKeyframe(Canvas *canvas)
1065 : BC_MenuItem(_("Projector keyframe"), _("Shift-F12"), KEY_F12)
1067 this->canvas = canvas;
1070 int CanvasPopupProjectorKeyframe::handle_event()
1072 canvas->projector_keyframe();
1078 CanvasPopupResetTranslation::CanvasPopupResetTranslation(Canvas *canvas)
1079 : BC_MenuItem(_("Reset translation"))
1081 this->canvas = canvas;
1083 int CanvasPopupResetTranslation::handle_event()
1085 canvas->reset_translation();
1091 CanvasToggleControls::CanvasToggleControls(Canvas *canvas)
1092 : BC_MenuItem(calculate_text(canvas->get_cwindow_controls()))
1094 this->canvas = canvas;
1096 int CanvasToggleControls::handle_event()
1098 canvas->toggle_controls();
1099 set_text(calculate_text(canvas->get_cwindow_controls()));
1103 char* CanvasToggleControls::calculate_text(int cwindow_controls)
1105 if(!cwindow_controls)
1106 return _("Show controls");
1108 return _("Hide controls");
1117 CanvasFullScreenItem::CanvasFullScreenItem(Canvas *canvas)
1118 : BC_MenuItem(_("Fullscreen"), "f", 'f')
1120 this->canvas = canvas;
1122 int CanvasFullScreenItem::handle_event()
1124 canvas->subwindow->unlock_window();
1125 canvas->use_fullscreen(1);
1126 canvas->subwindow->lock_window("CanvasFullScreenItem::handle_event");
1138 CanvasPopupRemoveSource::CanvasPopupRemoveSource(Canvas *canvas)
1139 : BC_MenuItem(_("Close source"))
1141 this->canvas = canvas;
1143 int CanvasPopupRemoveSource::handle_event()
1145 canvas->close_source();