Exciting new Alt/h help key provided by sge (Georgy) with many thanks!
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / zwindowgui.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 "bcwindow.h"
23 #include "canvas.h"
24 #include "edl.h"
25 #include "edlsession.h"
26 #include "keys.h"
27 #include "language.h"
28 #include "localsession.h"
29 #include "mainmenu.h"
30 #include "mainsession.h"
31 #include "mbuttons.h"
32 #include "mwindow.h"
33 #include "mwindowgui.h"
34 #include "playbackengine.h"
35 #include "theme.h"
36 #include "tracks.h"
37 #include "zwindow.h"
38 #include "zwindowgui.h"
39
40 ZWindowGUI::ZWindowGUI(MWindow *mwindow, ZWindow *zwindow, Mixer *mixer)
41  : BC_Window(zwindow->title, mixer->x, mixer->y, mixer->w, mixer->h,
42         xS(100), yS(75), 1, 1, 0)
43 {
44         this->mwindow = mwindow;
45         this->zwindow = zwindow;
46
47         canvas = 0;
48         playback_engine = 0;
49         highlighted = 0;
50         playable = zwindow->playable;
51 // *** CONTEXT_HELP ***
52         context_help_set_keyword("Multi-Camera");
53 }
54
55 ZWindowGUI::~ZWindowGUI()
56 {
57         delete playback_engine;
58         delete canvas;
59 }
60
61 void ZWindowGUI::create_objects()
62 {
63         lock_window("ZWindowGUI::create_objects");
64
65         canvas = new ZWindowCanvas(mwindow, this,
66                         xS(10),yS(10), get_w()-xS(20),get_h()-yS(20));
67         canvas->create_objects(mwindow->edl);
68         playback_engine = new PlaybackEngine(mwindow, canvas);
69         playback_engine->create_objects();
70
71         deactivate();
72         show_window();
73         unlock_window();
74 }
75
76 int ZWindowGUI::resize_event(int w, int h)
77 {
78         canvas->reposition_window(0,
79                         xS(10),yS(10), w-xS(20),h-yS(20));
80         zwindow->reposition(get_x(), get_y(), w, h);
81         BC_WindowBase::resize_event(w, h);
82         return 1;
83 }
84 int ZWindowGUI::translation_event()
85 {
86         return resize_event(get_w(),get_h());
87 }
88
89 int ZWindowGUI::close_event()
90 {
91         set_done(1);
92         return 1;
93 }
94
95 int ZWindowGUI::keypress_event()
96 {
97         int key = get_keypress();
98         if( key == 'w' || key == 'W' ) {
99                 close_event();
100                 return 1;
101         }
102         int result = 1;
103         switch( key ) {
104         case 'f': {
105                 int on = canvas->get_fullscreen() ? 0 : 1;
106                 canvas->set_fullscreen(on, 1);
107                 break; }
108         case ESC:
109                 canvas->set_fullscreen(0, 1);
110                 break;
111         default:
112                 unlock_window();
113                 mwindow->gui->lock_window("ZWindowGUI::keypress_event");
114                 result = mwindow->gui->mbuttons->transport->do_keypress(key);
115                 mwindow->gui->unlock_window();
116                 lock_window("ZWindowGUI::keypress_event 1");
117         }
118
119         if( !result )
120                 result = context_help_check_and_show();
121
122         return result;
123 }
124
125 int ZWindowGUI::button_press_event()
126 {
127         mwindow->select_zwindow(zwindow);
128         if( get_double_click() ) {
129                 unlock_window();
130                 mwindow->gui->lock_window("ZWindowGUI::button_press_event 0");
131                 LocalSession *local_session = mwindow->edl->local_session;
132                 double start = local_session->get_selectionstart(1);
133                 double end = local_session->get_selectionend(1);
134                 if( EQUIV(start, end) ) {
135                         start = mwindow->edl->tracks->total_recordable_length();
136                         if( start < 0 ) start = end;
137                 }
138                 if( (end-start) > 1e-4 && zwindow->edl ) {
139                         LocalSession *zlocal_session = zwindow->edl->local_session;
140                         zlocal_session->set_selectionstart(end);
141                         zlocal_session->set_selectionend(end);
142                         zlocal_session->set_inpoint(start);
143                         zlocal_session->set_outpoint(end);
144                         double orig_inpoint = local_session->get_inpoint();
145                         double orig_outpoint = local_session->get_outpoint();
146                         local_session->set_selectionstart(end);
147                         local_session->set_selectionend(end);
148                         local_session->set_inpoint(start);
149                         local_session->set_outpoint(end);
150                         mwindow->overwrite(zwindow->edl, 0);
151                         local_session->set_inpoint(orig_inpoint);
152                         local_session->set_outpoint(orig_outpoint);
153                         mwindow->gui->update_timebar(1);
154                 }
155                 mwindow->gui->unlock_window();
156                 lock_window("ZWindowGUI::button_press_event 1");
157         }
158         if( !canvas->get_canvas() ) return 0;
159         return canvas->button_press_event_base(canvas->get_canvas());
160 }
161
162 int ZWindowGUI::cursor_leave_event()
163 {
164         if( !canvas->get_canvas() ) return 0;
165         return canvas->cursor_leave_event_base(canvas->get_canvas());
166 }
167
168 int ZWindowGUI::cursor_enter_event()
169 {
170         if( !canvas->get_canvas() ) return 0;
171         return canvas->cursor_enter_event_base(canvas->get_canvas());
172 }
173
174 int ZWindowGUI::button_release_event()
175 {
176         if( !canvas->get_canvas() ) return 0;
177         return canvas->button_release_event();
178 }
179
180 int ZWindowGUI::cursor_motion_event()
181 {
182         BC_WindowBase *cvs = canvas->get_canvas();
183         if( !cvs ) return 0;
184         cvs->unhide_cursor();
185         return canvas->cursor_motion_event();
186 }
187
188 int ZWindowGUI::draw_overlays()
189 {
190         BC_WindowBase *cvs = canvas->get_canvas();
191         if( !cvs || cvs->get_video_on() ) return 0;
192         set_highlighted(zwindow->highlighted);
193         if( !playable ) set_playable(-1);
194         return 1;
195 }
196
197 void ZWindowGUI::set_highlighted(int v)
198 {
199         if( highlighted == v ) return;
200         highlighted = v;
201         BC_WindowBase *cvs = canvas->get_canvas();
202         cvs->set_color(WHITE);
203         cvs->set_inverse();
204         cvs->draw_rectangle(0, 0, cvs->get_w(), cvs->get_h());
205         cvs->draw_rectangle(1, 1, cvs->get_w() - 2, cvs->get_h() - 2);
206         cvs->set_opaque();
207 }
208
209 void ZWindowGUI::set_playable(int v)
210 {
211         if( playable == v ) return;
212         playable = v>0 ? 1 : 0;
213         zwindow->playable = playable;
214         BC_WindowBase *cvs = canvas->get_canvas();
215         cvs->set_color(WHITE);
216         cvs->set_inverse();
217         int dx = cvs->get_w()/16+1, dy = cvs->get_h()/16+1;
218         int x = xS(5), y = yS(5), lw = (dx + dy)/16+1;
219         cvs->set_line_width(lw);
220         cvs->draw_line(x, y, x+dx, y+dy);
221         cvs->draw_line(x, y+dy, x+dx, y);
222         cvs->set_opaque();
223         cvs->set_line_width(1);
224 }
225
226
227 ZWindowCanvasTileMixers::ZWindowCanvasTileMixers(ZWindowCanvas *canvas)
228  : BC_MenuItem(_("Tile Mixers"))
229 {
230         this->canvas = canvas;
231 }
232 int ZWindowCanvasTileMixers::handle_event()
233 {
234         canvas->mwindow->tile_mixers();
235         return 1;
236 }
237
238 ZWindowCanvasPlayable::ZWindowCanvasPlayable(ZWindowCanvas *canvas)
239  : BC_MenuItem(_("Playable"))
240 {
241         this->canvas = canvas;
242         set_checked(canvas->gui->zwindow->playable);
243 }
244 int ZWindowCanvasPlayable::handle_event()
245 {
246         int v = !get_checked() ? 1 : 0;
247         set_checked(v);
248         canvas->gui->set_playable(v);
249         canvas->get_canvas()->flash(1);
250         return 1;
251 }
252
253 ZWindowCanvas::ZWindowCanvas(MWindow *mwindow, ZWindowGUI *gui,
254                 int x, int y, int w, int h)
255  : Canvas(mwindow, gui, x,y, w,h, 0,0,0)
256 {
257         this->mwindow = mwindow;
258         this->gui = gui;
259 }
260
261 void ZWindowCanvas::create_objects(EDL *edl)
262 {
263         Canvas::create_objects(edl);
264         canvas_menu->add_item(new ZWindowCanvasTileMixers(this));
265         canvas_menu->add_item(new ZWindowCanvasPlayable(this));
266 }
267
268 void ZWindowCanvas::close_source()
269 {
270         gui->unlock_window();
271         gui->zwindow->zgui->playback_engine->interrupt_playback(1);
272         gui->lock_window("ZWindowCanvas::close_source");
273         EDL *edl = gui->zwindow->edl;
274         if( edl ) {
275                 gui->zwindow->edl = 0;
276                 edl->remove_user();
277         }
278 }
279
280 void ZWindowCanvas::draw_refresh(int flush)
281 {
282         EDL *edl = gui->zwindow->edl;
283         BC_WindowBase *cvs = get_canvas();
284         int dirty = 0;
285
286         if( !cvs->get_video_on() ) {
287                 cvs->clear_box(0, 0, cvs->get_w(), cvs->get_h());
288                 gui->highlighted = 0;
289                 dirty = 1;
290         }
291         if( !cvs->get_video_on() && refresh_frame && edl ) {
292                 float in_x1, in_y1, in_x2, in_y2;
293                 float out_x1, out_y1, out_x2, out_y2;
294                 get_transfers(edl,
295                         in_x1, in_y1, in_x2, in_y2,
296                         out_x1, out_y1, out_x2, out_y2);
297                 cvs->draw_vframe(refresh_frame,
298                         (int)out_x1, (int)out_y1, (int)(out_x2 - out_x1), (int)(out_y2 - out_y1),
299                         (int)in_x1, (int)in_y1, (int)(in_x2 - in_x1), (int)(in_y2 - in_y1), 0);
300                 dirty = 1;
301         }
302         
303         if( gui->draw_overlays() )
304                 dirty = 1;
305         if( dirty )
306                 cvs->flash(flush);
307 }
308
309 float ZWindowCanvas::get_auto_zoom()
310 {
311         EDL *edl = gui->zwindow->edl;
312         if( !edl ) edl = mwindow->edl;
313         float conformed_w, conformed_h;
314         edl->calculate_conformed_dimensions(0, conformed_w, conformed_h);
315         BC_WindowBase *window = get_canvas();
316         int cw = window ? window->get_w() : w;
317         int ch = window ? window->get_h() : h;
318         float zoom_x = cw / conformed_w;
319         float zoom_y = ch / conformed_h;
320         return zoom_x < zoom_y ? zoom_x : zoom_y;
321 }
322
323 float ZWindowCanvas::get_zoom()
324 {
325         return gui->zwindow->zoom;
326 }
327 void ZWindowCanvas::update_zoom(int x, int y, float zoom)
328 {
329         gui->zwindow->zoom = zoom;
330 }
331
332 void ZWindowCanvas::zoom_auto()
333 {
334         EDL *edl = gui->zwindow->edl;
335         if( !edl ) edl = mwindow->edl;
336         set_zoom(edl, 0);
337 }
338
339 void ZWindowCanvas::zoom_resize_window(float zoom)
340 {
341         if( !zoom ) zoom = get_auto_zoom();
342         EDL *edl = gui->zwindow->edl;
343         if( !edl ) edl = mwindow->edl;
344         int ow = edl->session->output_w, oh = edl->session->output_h;
345         int canvas_w, canvas_h;
346         calculate_sizes(mwindow->edl->get_aspect_ratio(), ow, oh,
347                 zoom, canvas_w, canvas_h);
348         int new_w = canvas_w + xS(20);
349         int new_h = canvas_h + yS(20);
350         gui->resize_window(new_w, new_h);
351         gui->resize_event(new_w, new_h);
352 }
353