rework android-rmt display, add a few buttons
[goodguy/history.git] / cinelerra-5.0 / cinelerra / cwindowtool.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008-2014 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 "automation.h"
23 #include "cicolors.h"
24 #include "clip.h"
25 #include "condition.h"
26 #include "cpanel.h"
27 #include "cplayback.h"
28 #include "cwindow.h"
29 #include "cwindowgui.h"
30 #include "cwindowtool.h"
31 #include "edl.h"
32 #include "edlsession.h"
33 #include "floatauto.h"
34 #include "floatautos.h"
35 #include "keys.h"
36 #include "language.h"
37 #include "localsession.h"
38 #include "mainsession.h"
39 #include "mainundo.h"
40 #include "maskauto.h"
41 #include "maskautos.h"
42 #include "mutex.h"
43 #include "mwindow.h"
44 #include "mwindowgui.h"
45 #include "theme.h"
46 #include "track.h"
47 #include "trackcanvas.h"
48 #include "transportque.h"
49
50
51 CWindowTool::CWindowTool(MWindow *mwindow, CWindowGUI *gui)
52  : Thread(1, 0, 0)
53 {
54         this->mwindow = mwindow;
55         this->gui = gui;
56         tool_gui = 0;
57         done = 0;
58         current_tool = CWINDOW_NONE;
59         set_synchronous(1);
60         input_lock = new Condition(0, "CWindowTool::input_lock");
61         output_lock = new Condition(1, "CWindowTool::output_lock");
62         tool_gui_lock = new Mutex("CWindowTool::tool_gui_lock");
63 }
64
65 CWindowTool::~CWindowTool()
66 {
67         done = 1;
68         stop_tool();
69         input_lock->unlock();
70         Thread::join();
71         delete input_lock;
72         delete output_lock;
73         delete tool_gui_lock;
74 }
75
76 void CWindowTool::start_tool(int operation)
77 {
78         CWindowToolGUI *new_gui = 0;
79         int result = 0;
80
81 //printf("CWindowTool::start_tool 1\n");
82         if(current_tool != operation)
83         {
84                 current_tool = operation;
85                 switch(operation)
86                 {
87                         case CWINDOW_EYEDROP:
88                                 new_gui = new CWindowEyedropGUI(mwindow, this);
89                                 break;
90                         case CWINDOW_CROP:
91                                 new_gui = new CWindowCropGUI(mwindow, this);
92                                 break;
93                         case CWINDOW_CAMERA:
94                                 new_gui = new CWindowCameraGUI(mwindow, this);
95                                 break;
96                         case CWINDOW_PROJECTOR:
97                                 new_gui = new CWindowProjectorGUI(mwindow, this);
98                                 break;
99                         case CWINDOW_MASK:
100                                 new_gui = new CWindowMaskGUI(mwindow, this);
101                                 break;
102                         case CWINDOW_RULER:
103                                 new_gui = new CWindowRulerGUI(mwindow, this);
104                                 break;
105                         default:
106                                 result = 1;
107                                 stop_tool();
108                                 break;
109                 }
110
111 //printf("CWindowTool::start_tool 1\n");
112
113
114                 if(!result)
115                 {
116                         stop_tool();
117 // Wait for previous tool GUI to finish
118                         output_lock->lock("CWindowTool::start_tool");
119                         this->tool_gui = new_gui;
120                         tool_gui->create_objects();
121                         
122                         if(mwindow->edl->session->tool_window &&
123                                 mwindow->session->show_cwindow) tool_gui->show_window();
124                         tool_gui->lock_window("CWindowTool::start_tool 1");
125                         tool_gui->flush();
126                         tool_gui->unlock_window();
127                         
128                         
129 // Signal thread to run next tool GUI
130                         input_lock->unlock();
131                 }
132 //printf("CWindowTool::start_tool 1\n");
133         }
134         else
135         if(tool_gui) 
136         {
137                 tool_gui->lock_window("CWindowTool::start_tool");
138                 tool_gui->update();
139                 tool_gui->unlock_window();
140         }
141
142 //printf("CWindowTool::start_tool 2\n");
143
144 }
145
146
147 void CWindowTool::stop_tool()
148 {
149         if(tool_gui)
150         {
151                 tool_gui->lock_window("CWindowTool::stop_tool");
152                 tool_gui->set_done(0);
153                 tool_gui->unlock_window();
154         }
155 }
156
157 void CWindowTool::show_tool()
158 {
159         if(tool_gui && mwindow->edl->session->tool_window)
160         {
161                 tool_gui->lock_window("CWindowTool::show_tool");
162                 tool_gui->show_window();
163                 tool_gui->unlock_window();
164         }
165 }
166
167 void CWindowTool::hide_tool()
168 {
169         if(tool_gui && mwindow->edl->session->tool_window)
170         {
171                 tool_gui->lock_window("CWindowTool::show_tool");
172                 tool_gui->hide_window();
173                 tool_gui->unlock_window();
174         }
175 }
176
177
178 void CWindowTool::run()
179 {
180         while(!done)
181         {
182                 input_lock->lock("CWindowTool::run");
183                 if(!done)
184                 {
185                         tool_gui->run_window();
186                         tool_gui_lock->lock("CWindowTool::run");
187                         delete tool_gui;
188                         tool_gui = 0;
189                         tool_gui_lock->unlock();
190                 }
191                 output_lock->unlock();
192         }
193 }
194
195 void CWindowTool::update_show_window()
196 {
197         if(tool_gui)
198         {
199                 tool_gui->lock_window("CWindowTool::update_show_window");
200
201                 if(mwindow->edl->session->tool_window) 
202                 {
203                         tool_gui->update();
204                         tool_gui->show_window();
205                 }
206                 else
207                         tool_gui->hide_window();
208                 tool_gui->flush();
209
210                 tool_gui->unlock_window();
211         }
212 }
213
214 void CWindowTool::raise_window()
215 {
216         if(tool_gui)
217         {
218                 gui->unlock_window();
219                 tool_gui->lock_window("CWindowTool::raise_window");
220                 tool_gui->raise_window();
221                 tool_gui->unlock_window();
222                 gui->lock_window("CWindowTool::raise_window");
223         }
224 }
225
226 void CWindowTool::update_values()
227 {
228         tool_gui_lock->lock("CWindowTool::update_values");
229         if(tool_gui)
230         {
231                 tool_gui->lock_window("CWindowTool::update_values");
232                 tool_gui->update();
233                 tool_gui->flush();
234                 tool_gui->unlock_window();
235         }
236         tool_gui_lock->unlock();
237 }
238
239
240
241
242
243
244
245 CWindowToolGUI::CWindowToolGUI(MWindow *mwindow, 
246         CWindowTool *thread, 
247         const char *title,
248         int w, 
249         int h)
250  : BC_Window(title,
251         mwindow->session->ctool_x,
252         mwindow->session->ctool_y,
253         w,
254         h,
255         w,
256         h,
257         0,
258         0,
259         1)
260 {
261         this->mwindow = mwindow;
262         this->thread = thread;
263         current_operation = 0;
264 }
265
266 CWindowToolGUI::~CWindowToolGUI()
267 {
268 }
269
270 int CWindowToolGUI::close_event()
271 {
272         hide_window();
273         flush();
274         mwindow->edl->session->tool_window = 0;
275         unlock_window();
276
277
278
279         thread->gui->lock_window("CWindowToolGUI::close_event");
280         thread->gui->composite_panel->set_operation(mwindow->edl->session->cwindow_operation);
281         thread->gui->flush();
282         thread->gui->unlock_window();
283
284         lock_window("CWindowToolGUI::close_event");
285         return 1;
286 ;}
287
288 int CWindowToolGUI::keypress_event()
289 {
290         if(get_keypress() == 'w' || get_keypress() == 'W')
291                 return close_event();
292         return 0;
293 }
294
295 int CWindowToolGUI::translation_event()
296 {
297         mwindow->session->ctool_x = get_x();
298         mwindow->session->ctool_y = get_y();
299         return 0;
300 }
301
302
303
304
305
306
307 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value)
308  : BC_TumbleTextBox(gui, 
309                 (float)value,
310                 (float)-65536,
311                 (float)65536,
312                 x, 
313                 y, 
314                 100)
315 {
316         this->gui = gui;
317 }
318
319 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
320  : BC_TumbleTextBox(gui, 
321                 (int64_t)value,
322                 (int64_t)-65536,
323                 (int64_t)65536,
324                 x, 
325                 y, 
326                 100)
327 {
328         this->gui = gui;
329 }
330 int CWindowCoord::handle_event()
331 {
332         gui->event_caller = this;
333         gui->handle_event();
334         return 1;
335 }
336
337
338 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
339  : BC_GenericButton(x, y, _("Do it"))
340 {
341         this->mwindow = mwindow;
342         this->gui = gui;
343 }
344 int CWindowCropOK::handle_event()
345 {
346         mwindow->crop_video();
347         return 1;
348 }
349
350
351 int CWindowCropOK::keypress_event()
352 {
353         if(get_keypress() == 0xd) 
354         {
355                 handle_event();
356                 return 1;
357         }
358         return 0;
359 }
360
361
362
363
364
365
366
367 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
368  : CWindowToolGUI(mwindow, 
369         thread,
370         _(PROGRAM_NAME ": Crop"),
371         330,
372         100)
373 {
374 }
375
376
377 CWindowCropGUI::~CWindowCropGUI()
378 {
379 }
380
381 void CWindowCropGUI::create_objects()
382 {
383         int x = 10, y = 10;
384         BC_Title *title;
385
386         lock_window("CWindowCropGUI::create_objects");
387         int column1 = 0;
388         int pad = MAX(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1), 
389                 BC_Title::calculate_h(this, "X")) + 5;
390         add_subwindow(title = new BC_Title(x, y, _("X1:")));
391         column1 = MAX(column1, title->get_w());
392         y += pad;
393         add_subwindow(title = new BC_Title(x, y, _("W:")));
394         column1 = MAX(column1, title->get_w());
395         y += pad;
396         add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
397
398         x += column1 + 5;
399         y = 10;
400         x1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_x1);
401         x1->create_objects();
402         y += pad;
403         width = new CWindowCoord(thread->tool_gui, 
404                 x, 
405                 y, 
406                 mwindow->edl->session->crop_x2 - 
407                         mwindow->edl->session->crop_x1);
408         width->create_objects();
409
410
411         x += x1->get_w() + 10;
412         y = 10;
413         int column2 = 0;
414         add_subwindow(title = new BC_Title(x, y, _("Y1:")));
415         column2 = MAX(column2, title->get_w());
416         y += pad;
417         add_subwindow(title = new BC_Title(x, y, _("H:")));
418         column2 = MAX(column2, title->get_w());
419         y += pad;
420
421         y = 10;
422         x += column2 + 5;
423         y1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_y1);
424         y1->create_objects();
425         y += pad;
426         height = new CWindowCoord(thread->tool_gui, 
427                 x, 
428                 y, 
429                 mwindow->edl->session->crop_y2 - 
430                         mwindow->edl->session->crop_y1);
431         height->create_objects();
432         unlock_window();
433 }
434
435 void CWindowCropGUI::handle_event()
436 {
437         int new_x1, new_y1;
438         new_x1 = atol(x1->get_text());
439         new_y1 = atol(y1->get_text());
440         if(new_x1 != mwindow->edl->session->crop_x1)
441         {
442                 mwindow->edl->session->crop_x2 = new_x1 +
443                         mwindow->edl->session->crop_x2 - 
444                         mwindow->edl->session->crop_x1;
445                 mwindow->edl->session->crop_x1 = new_x1;
446         }
447         if(new_y1 != mwindow->edl->session->crop_y1)
448         {
449                 mwindow->edl->session->crop_y2 = new_y1 +
450                         mwindow->edl->session->crop_y2 -
451                         mwindow->edl->session->crop_y1;
452                 mwindow->edl->session->crop_y1 = atol(y1->get_text());
453         }
454         mwindow->edl->session->crop_x2 = atol(width->get_text()) + 
455                 mwindow->edl->session->crop_x1;
456         mwindow->edl->session->crop_y2 = atol(height->get_text()) + 
457                 mwindow->edl->session->crop_y1;
458         update();
459         mwindow->cwindow->gui->lock_window("CWindowCropGUI::handle_event");
460         mwindow->cwindow->gui->canvas->draw_refresh();
461         mwindow->cwindow->gui->unlock_window();
462 }
463
464 void CWindowCropGUI::update()
465 {
466         x1->update((int64_t)mwindow->edl->session->crop_x1);
467         y1->update((int64_t)mwindow->edl->session->crop_y1);
468         width->update((int64_t)mwindow->edl->session->crop_x2 - 
469                 mwindow->edl->session->crop_x1);
470         height->update((int64_t)mwindow->edl->session->crop_y2 - 
471                 mwindow->edl->session->crop_y1);
472 }
473
474
475
476
477
478
479 CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
480  : CWindowToolGUI(mwindow, 
481         thread,
482         _(PROGRAM_NAME ": Color"),
483         200,
484         250)
485 {
486 }
487
488 CWindowEyedropGUI::~CWindowEyedropGUI()
489 {
490 }
491
492 void CWindowEyedropGUI::create_objects()
493 {
494         int margin = mwindow->theme->widget_border;
495         int x = margin;
496         int y = margin;
497         int x2 = 70;
498         lock_window("CWindowEyedropGUI::create_objects");
499         BC_Title *title1, *title2, *title3, *title4, *title5, *title6, *title7;
500         add_subwindow(title7 = new BC_Title(x, y, _("Radius:")));
501         y += BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1) + margin;
502         
503         add_subwindow(title1 = new BC_Title(x, y, _("Red:")));
504         y += title1->get_h() + margin;
505         add_subwindow(title2 = new BC_Title(x, y, _("Green:")));
506         y += title2->get_h() + margin;
507         add_subwindow(title3 = new BC_Title(x, y, _("Blue:")));
508         y += title3->get_h() + margin;
509
510         add_subwindow(title4 = new BC_Title(x, y, "Y:"));
511         y += title4->get_h() + margin;
512         add_subwindow(title5 = new BC_Title(x, y, "U:"));
513         y += title5->get_h() + margin;
514         add_subwindow(title6 = new BC_Title(x, y, "V:"));
515
516
517         radius = new CWindowCoord(this,
518                 x2,
519                 title7->get_y(),
520                 mwindow->edl->session->eyedrop_radius);
521         radius->create_objects();
522         radius->set_boundaries((int64_t)0, (int64_t)255);
523
524
525         add_subwindow(red = new BC_Title(x2, title1->get_y(), "0"));
526         add_subwindow(green = new BC_Title(x2, title2->get_y(), "0"));
527         add_subwindow(blue = new BC_Title(x2, title3->get_y(), "0"));
528
529         add_subwindow(this->y = new BC_Title(x2, title4->get_y(), "0"));
530         add_subwindow(this->u = new BC_Title(x2, title5->get_y(), "0"));
531         add_subwindow(this->v = new BC_Title(x2, title6->get_y(), "0"));
532
533         y = title6->get_y() + this->v->get_h() + margin;
534         add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
535         update();
536         unlock_window();
537 }
538
539 void CWindowEyedropGUI::update()
540 {
541         radius->update((int64_t)mwindow->edl->session->eyedrop_radius);
542
543         red->update(mwindow->edl->local_session->red);
544         green->update(mwindow->edl->local_session->green);
545         blue->update(mwindow->edl->local_session->blue);
546
547         float y, u, v;
548         YUV::rgb_to_yuv_f(mwindow->edl->local_session->red, 
549                 mwindow->edl->local_session->green, 
550                 mwindow->edl->local_session->blue, 
551                 y, 
552                 u, 
553                 v);
554         this->y->update(y);
555         this->u->update(u);
556         this->v->update(v);
557
558         int red = (int)(CLIP(mwindow->edl->local_session->red, 0, 1) * 0xff);
559         int green = (int)(CLIP(mwindow->edl->local_session->green, 0, 1) * 0xff);
560         int blue = (int)(CLIP(mwindow->edl->local_session->blue, 0, 1) * 0xff);
561         sample->set_color((red << 16) | (green << 8) | blue);
562         sample->draw_box(0, 0, sample->get_w(), sample->get_h());
563         sample->set_color(BLACK);
564         sample->draw_rectangle(0, 0, sample->get_w(), sample->get_h());
565         sample->flash();
566 }
567
568 void CWindowEyedropGUI::handle_event()
569 {
570         int new_radius = atoi(radius->get_text());
571         if(new_radius != mwindow->edl->session->eyedrop_radius)
572         {
573                 CWindowGUI *gui = mwindow->cwindow->gui;
574                 if(gui->eyedrop_visible)
575                 {
576                         gui->lock_window("CWindowEyedropGUI::handle_event");
577 // hide it
578                         int rerender;
579                         gui->canvas->do_eyedrop(rerender, 0, 1);
580                 }
581
582                 mwindow->edl->session->eyedrop_radius = new_radius;
583
584                 if(gui->eyedrop_visible)
585                 {
586 // draw it
587                         int rerender;
588                         gui->canvas->do_eyedrop(rerender, 0, 1);
589                         gui->unlock_window();
590                 }
591         }
592 }
593
594
595
596
597
598
599
600
601
602 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
603  : CWindowToolGUI(mwindow, 
604         thread,
605         _(PROGRAM_NAME ": Camera"),
606         170,
607         170)
608 {
609 }
610 CWindowCameraGUI::~CWindowCameraGUI()
611 {
612 }
613
614 void CWindowCameraGUI::create_objects()
615 {
616         int x = 10, y = 10, x1;
617         Track *track = mwindow->cwindow->calculate_affected_track();
618         FloatAuto *x_auto = 0;
619         FloatAuto *y_auto = 0;
620         FloatAuto *z_auto = 0;
621         BC_Title *title;
622         BC_Button *button;
623
624         lock_window("CWindowCameraGUI::create_objects");
625         if(track)
626         {
627                 mwindow->cwindow->calculate_affected_autos(&x_auto,
628                         &y_auto,
629                         &z_auto,
630                         track,
631                         1,
632                         0,
633                         0,
634                         0);
635         }
636
637         add_subwindow(title = new BC_Title(x, y, _("X:")));
638         x += title->get_w();
639         this->x = new CWindowCoord(this, 
640                 x, 
641                 y, 
642                 x_auto ? x_auto->value : (float)0);
643         this->x->create_objects();
644
645         
646         y += 30;
647         x = 10;
648         add_subwindow(title = new BC_Title(x, y, _("Y:")));
649         x += title->get_w();
650         this->y = new CWindowCoord(this, 
651                 x, 
652                 y, 
653                 y_auto ? y_auto->value : (float)0);
654         this->y->create_objects();
655         y += 30;
656         x = 10;
657         add_subwindow(title = new BC_Title(x, y, _("Z:")));
658         x += title->get_w();
659         this->z = new CWindowCoord(this, 
660                 x, 
661                 y, 
662                 z_auto ? z_auto->value : (float)1);
663         this->z->create_objects();
664         this->z->set_increment(0.01);
665
666         y += 30;
667         x1 = 10;
668         add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
669         x1 += button->get_w();
670         add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
671         x1 += button->get_w();
672         add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
673
674         y += button->get_h();
675         x1 = 10;
676         add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
677         x1 += button->get_w();
678         add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
679         x1 += button->get_w();
680         add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
681         unlock_window();
682 }
683
684 void CWindowCameraGUI::update_preview()
685 {
686         mwindow->restart_brender();
687         mwindow->sync_parameters(CHANGE_PARAMS);
688
689         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
690                         CHANGE_NONE,
691                         mwindow->edl,
692                         1);
693         mwindow->cwindow->gui->lock_window("CWindowCameraGUI::update_preview");
694         mwindow->cwindow->gui->canvas->draw_refresh();
695         mwindow->cwindow->gui->unlock_window();
696 }
697
698
699 void CWindowCameraGUI::handle_event()
700 {
701         FloatAuto *x_auto = 0;
702         FloatAuto *y_auto = 0;
703         FloatAuto *z_auto = 0;
704         Track *track = mwindow->cwindow->calculate_affected_track();
705         if(track)
706         {
707                 mwindow->undo->update_undo_before(_("camera"), this);
708                 if(event_caller == x)
709                 {
710                         x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
711                                 track->automation->autos[AUTOMATION_CAMERA_X],
712                                 1);
713                         if(x_auto)
714                         {
715                                 x_auto->value = atof(x->get_text());
716                                 update_preview();
717                         }
718                 }
719                 else
720                 if(event_caller == y)
721                 {
722                         y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
723                                 track->automation->autos[AUTOMATION_CAMERA_Y],
724                                 1);
725                         if(y_auto)
726                         {
727                                 y_auto->value = atof(y->get_text());
728                                 update_preview();
729                         }
730                 }
731                 else
732                 if(event_caller == z)
733                 {
734                         z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
735                                 track->automation->autos[AUTOMATION_CAMERA_Z],
736                                 1);
737                         if(z_auto)
738                         {
739                                 float zoom = atof(z->get_text());
740                                 if(zoom > 10) zoom = 10; 
741                                 else
742                                 if(zoom < 0) zoom = 0;
743         // Doesn't allow user to enter from scratch
744         //              if(zoom != atof(z->get_text())) 
745         //                      z->update(zoom);
746
747                                 z_auto->value = zoom;
748                                 mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
749                                 mwindow->gui->draw_overlays(1);
750                                 mwindow->gui->unlock_window();
751                                 update_preview();
752                         }
753                 }
754
755                 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
756         }
757 }
758
759 void CWindowCameraGUI::update()
760 {
761         FloatAuto *x_auto = 0;
762         FloatAuto *y_auto = 0;
763         FloatAuto *z_auto = 0;
764         Track *track = mwindow->cwindow->calculate_affected_track();
765
766         if(track)
767         {
768                 mwindow->cwindow->calculate_affected_autos(&x_auto,
769                         &y_auto,
770                         &z_auto,
771                         track,
772                         1,
773                         0,
774                         0,
775                         0);
776         }
777
778         if(x_auto)
779                 x->update(x_auto->value);
780         if(y_auto)
781                 y->update(y_auto->value);
782         if(z_auto)
783                 z->update(z_auto->value);
784 }
785
786 // BezierAuto* CWindowCameraGUI::get_keyframe()
787 // {
788 //      BezierAuto *keyframe = 0;
789 //      Track *track = mwindow->cwindow->calculate_affected_track();
790 //      if(track)
791 //              keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
792 //                      track->automation->autos[AUTOMATION_CAMERA]);
793 //      return keyframe;
794 // }
795
796
797
798 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
799  : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
800 {
801         this->gui = gui;
802         this->mwindow = mwindow;
803         set_tooltip(_("Left justify"));
804 }
805 int CWindowCameraLeft::handle_event()
806 {
807         FloatAuto *x_auto = 0;
808         FloatAuto *z_auto = 0;
809         Track *track = mwindow->cwindow->calculate_affected_track();
810         if(track)
811         {
812                 mwindow->cwindow->calculate_affected_autos(&x_auto,
813                         0,
814                         &z_auto,
815                         track,
816                         1,
817                         1,
818                         0,
819                         0);
820         }
821
822         if(x_auto && z_auto)
823         {
824                 int w = 0, h = 0;
825                 track->get_source_dimensions(
826                         mwindow->edl->local_session->get_selectionstart(1),
827                         w,
828                         h);
829
830                 if(w && h)
831                 {
832                         mwindow->undo->update_undo_before(_("camera"), 0);
833                         x_auto->value = 
834                                 (double)track->track_w / z_auto->value / 2 - 
835                                 (double)w / 2;
836                         mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
837                         gui->update();
838                         gui->update_preview();
839                 }
840         }
841
842         return 1;
843 }
844
845
846 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
847  : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
848 {
849         this->gui = gui;
850         this->mwindow = mwindow;
851         set_tooltip(_("Center horizontal"));
852 }
853 int CWindowCameraCenter::handle_event()
854 {
855         FloatAuto *x_auto = 0;
856         Track *track = mwindow->cwindow->calculate_affected_track();
857         if(track)
858                 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
859                         track->automation->autos[AUTOMATION_CAMERA_X],
860                         1);
861
862         if(x_auto)
863         {
864                 mwindow->undo->update_undo_before(_("camera"), 0);
865                 x_auto->value = 0;
866                 gui->update();
867                 gui->update_preview();
868                 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
869         }
870
871         return 1;
872 }
873
874
875 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
876  : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
877 {
878         this->gui = gui;
879         this->mwindow = mwindow;
880         set_tooltip(_("Right justify"));
881 }
882 int CWindowCameraRight::handle_event()
883 {
884         FloatAuto *x_auto = 0;
885         FloatAuto *z_auto = 0;
886         Track *track = mwindow->cwindow->calculate_affected_track();
887         if(track)
888         {
889                 mwindow->cwindow->calculate_affected_autos(&x_auto,
890                         0,
891                         &z_auto,
892                         track,
893                         1,
894                         1,
895                         0,
896                         0);
897         }
898
899         if(x_auto && z_auto)
900         {
901                 int w = 0, h = 0;
902                 track->get_source_dimensions(
903                         mwindow->edl->local_session->get_selectionstart(1),
904                         w,
905                         h);
906
907                 if(w && h)
908                 {
909                         mwindow->undo->update_undo_before(_("camera"), 0);
910                         x_auto->value = -((double)track->track_w / z_auto->value / 2 - 
911                                 (double)w / 2);
912                         gui->update();
913                         gui->update_preview();
914                         mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
915                 }
916         }
917
918         return 1;
919 }
920
921
922 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
923  : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
924 {
925         this->gui = gui;
926         this->mwindow = mwindow;
927         set_tooltip(_("Top justify"));
928 }
929 int CWindowCameraTop::handle_event()
930 {
931         FloatAuto *y_auto = 0;
932         FloatAuto *z_auto = 0;
933         Track *track = mwindow->cwindow->calculate_affected_track();
934         if(track)
935         {
936                 mwindow->cwindow->calculate_affected_autos(0,
937                         &y_auto,
938                         &z_auto,
939                         track,
940                         1,
941                         0,
942                         1,
943                         0);
944         }
945
946         if(y_auto && z_auto)
947         {
948                 int w = 0, h = 0;
949                 track->get_source_dimensions(
950                         mwindow->edl->local_session->get_selectionstart(1),
951                         w,
952                         h);
953
954                 if(w && h)
955                 {
956                         mwindow->undo->update_undo_before(_("camera"), 0);
957                         y_auto->value = (double)track->track_h / z_auto->value / 2 - 
958                                 (double)h / 2;
959                         gui->update();
960                         gui->update_preview();
961                         mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
962                 }
963         }
964
965         return 1;
966 }
967
968
969 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
970  : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
971 {
972         this->gui = gui;
973         this->mwindow = mwindow;
974         set_tooltip(_("Center vertical"));
975 }
976 int CWindowCameraMiddle::handle_event()
977 {
978         FloatAuto *y_auto = 0;
979         Track *track = mwindow->cwindow->calculate_affected_track();
980         if(track)
981                 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
982                         track->automation->autos[AUTOMATION_CAMERA_Y], 1);
983
984         if(y_auto)
985         {
986                 mwindow->undo->update_undo_before(_("camera"), 0);
987                 y_auto->value = 0;
988                 gui->update();
989                 gui->update_preview();
990                 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
991         }
992
993         return 1;
994 }
995
996
997 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
998  : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
999 {
1000         this->gui = gui;
1001         this->mwindow = mwindow;
1002         set_tooltip(_("Bottom justify"));
1003 }
1004 int CWindowCameraBottom::handle_event()
1005 {
1006         FloatAuto *y_auto = 0;
1007         FloatAuto *z_auto = 0;
1008         Track *track = mwindow->cwindow->calculate_affected_track();
1009         if(track)
1010         {
1011                 mwindow->cwindow->calculate_affected_autos(0,
1012                         &y_auto,
1013                         &z_auto,
1014                         track,
1015                         1,
1016                         0,
1017                         1,
1018                         0);
1019         }
1020
1021         if(y_auto && z_auto)
1022         {
1023                 int w = 0, h = 0;
1024                 track->get_source_dimensions(
1025                         mwindow->edl->local_session->get_selectionstart(1),
1026                         w,
1027                         h);
1028
1029                 if(w && h)
1030                 {
1031                         mwindow->undo->update_undo_before(_("camera"), 0);
1032                         y_auto->value = -((double)track->track_h / z_auto->value / 2 - 
1033                                 (double)h / 2);
1034                         gui->update();
1035                         gui->update_preview();
1036                         mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1037                 }
1038         }
1039
1040         return 1;
1041 }
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
1060  : CWindowToolGUI(mwindow, 
1061         thread,
1062         _(PROGRAM_NAME ": Projector"),
1063         170,
1064         170)
1065 {
1066 }
1067 CWindowProjectorGUI::~CWindowProjectorGUI()
1068 {
1069 }
1070 void CWindowProjectorGUI::create_objects()
1071 {
1072         int x = 10, y = 10, x1;
1073         Track *track = mwindow->cwindow->calculate_affected_track();
1074         FloatAuto *x_auto = 0;
1075         FloatAuto *y_auto = 0;
1076         FloatAuto *z_auto = 0;
1077         BC_Title *title;
1078         BC_Button *button;
1079
1080         lock_window("CWindowProjectorGUI::create_objects");
1081         if(track)
1082         {
1083                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1084                         &y_auto,
1085                         &z_auto,
1086                         track,
1087                         0,
1088                         0,
1089                         0,
1090                         0);
1091         }
1092
1093         add_subwindow(title = new BC_Title(x, y, _("X:")));
1094         x += title->get_w();
1095         this->x = new CWindowCoord(this, 
1096                 x, 
1097                 y, 
1098                 x_auto ? x_auto->value : (float)0);
1099         this->x->create_objects();
1100         y += 30;
1101         x = 10;
1102         add_subwindow(title = new BC_Title(x, y, _("Y:")));
1103         x += title->get_w();
1104         this->y = new CWindowCoord(this, 
1105                 x, 
1106                 y, 
1107                 y_auto ? y_auto->value : (float)0);
1108         this->y->create_objects();
1109         y += 30;
1110         x = 10;
1111         add_subwindow(title = new BC_Title(x, y, _("Z:")));
1112         x += title->get_w();
1113         this->z = new CWindowCoord(this, 
1114                 x, 
1115                 y, 
1116                 z_auto ? z_auto->value : (float)1);
1117         this->z->create_objects();
1118         this->z->set_increment(0.01);
1119
1120         y += 30;
1121         x1 = 10;
1122         add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
1123         x1 += button->get_w();
1124         add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
1125         x1 += button->get_w();
1126         add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
1127
1128         y += button->get_h();
1129         x1 = 10;
1130         add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
1131         x1 += button->get_w();
1132         add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
1133         x1 += button->get_w();
1134         add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
1135         unlock_window();
1136 }
1137
1138 void CWindowProjectorGUI::update_preview()
1139 {
1140         mwindow->restart_brender();
1141         mwindow->sync_parameters(CHANGE_PARAMS);
1142         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1143                         CHANGE_NONE,
1144                         mwindow->edl,
1145                         1);
1146         mwindow->cwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
1147         mwindow->cwindow->gui->canvas->draw_refresh();
1148         mwindow->cwindow->gui->unlock_window();
1149 }
1150
1151 void CWindowProjectorGUI::handle_event()
1152 {
1153         FloatAuto *x_auto = 0;
1154         FloatAuto *y_auto = 0;
1155         FloatAuto *z_auto = 0;
1156         Track *track = mwindow->cwindow->calculate_affected_track();
1157
1158         if(track)
1159         {
1160                 mwindow->undo->update_undo_before(_("projector"), this);
1161                 if(event_caller == x)
1162                 {
1163                         x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1164                                 track->automation->autos[AUTOMATION_PROJECTOR_X],
1165                                 1);
1166                         if(x_auto)
1167                         {
1168                                 x_auto->value = atof(x->get_text());
1169                                 update_preview();
1170                         }
1171                 }
1172                 else
1173                 if(event_caller == y)
1174                 {
1175                         y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1176                                 track->automation->autos[AUTOMATION_PROJECTOR_Y],
1177                                 1);
1178                         if(y_auto)
1179                         {
1180                                 y_auto->value = atof(y->get_text());
1181                                 update_preview();
1182                         }
1183                 }
1184                 else
1185                 if(event_caller == z)
1186                 {
1187                         z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1188                                 track->automation->autos[AUTOMATION_PROJECTOR_Z],
1189                                 1);
1190                         if(z_auto)
1191                         {
1192                                 float zoom = atof(z->get_text());
1193                                 if(zoom > 10000) zoom = 10000; 
1194                                 else 
1195                                 if(zoom < 0) zoom = 0;
1196 //                      if (zoom != atof(z->get_text())) 
1197 //                              z->update(zoom);
1198                                 z_auto->value = zoom;
1199
1200                                 mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
1201                                 mwindow->gui->draw_overlays(1);
1202                                 mwindow->gui->unlock_window();
1203
1204                                 update_preview();
1205                         }
1206                 }
1207                 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1208         }
1209 }
1210
1211 void CWindowProjectorGUI::update()
1212 {
1213         FloatAuto *x_auto = 0;
1214         FloatAuto *y_auto = 0;
1215         FloatAuto *z_auto = 0;
1216         Track *track = mwindow->cwindow->calculate_affected_track();
1217
1218         if(track)
1219         {
1220                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1221                         &y_auto,
1222                         &z_auto,
1223                         track,
1224                         0,
1225                         0,
1226                         0,
1227                         0);
1228         }
1229
1230         if(x_auto)
1231                 x->update(x_auto->value);
1232         if(y_auto)
1233                 y->update(y_auto->value);
1234         if(z_auto)
1235                 z->update(z_auto->value);
1236 }
1237
1238 // BezierAuto* CWindowProjectorGUI::get_keyframe()
1239 // {
1240 //      BezierAuto *keyframe = 0;
1241 //      Track *track = mwindow->cwindow->calculate_affected_track();
1242 //      if(track)
1243 //              keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
1244 //                      track->automation->autos[AUTOMATION_PROJECTOR]);
1245 //      return keyframe;
1246 // }
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1286  : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
1287 {
1288         this->gui = gui;
1289         this->mwindow = mwindow;
1290         set_tooltip(_("Left justify"));
1291 }
1292 int CWindowProjectorLeft::handle_event()
1293 {
1294         FloatAuto *x_auto = 0;
1295         FloatAuto *z_auto = 0;
1296         Track *track = mwindow->cwindow->calculate_affected_track();
1297         if(track)
1298         {
1299                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1300                         0,
1301                         &z_auto,
1302                         track,
1303                         0,
1304                         1,
1305                         0,
1306                         0);
1307         }
1308         if(x_auto && z_auto)
1309         {
1310                 mwindow->undo->update_undo_before(_("projector"), 0);
1311                 x_auto->value = (double)track->track_w * z_auto->value / 2 - 
1312                         (double)mwindow->edl->session->output_w / 2;
1313                 gui->update();
1314                 gui->update_preview();
1315                 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1316         }
1317
1318         return 1;
1319 }
1320
1321
1322 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1323  : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
1324 {
1325         this->gui = gui;
1326         this->mwindow = mwindow;
1327         set_tooltip(_("Center horizontal"));
1328 }
1329 int CWindowProjectorCenter::handle_event()
1330 {
1331         FloatAuto *x_auto = 0;
1332         Track *track = mwindow->cwindow->calculate_affected_track();
1333         if(track)
1334                 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1335                         track->automation->autos[AUTOMATION_PROJECTOR_X],
1336                         1);
1337
1338         if(x_auto)
1339         {
1340                 mwindow->undo->update_undo_before(_("projector"), 0);
1341                 x_auto->value = 0;
1342                 gui->update();
1343                 gui->update_preview();
1344                 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1345         }
1346
1347         return 1;
1348 }
1349
1350
1351 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1352  : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
1353 {
1354         this->gui = gui;
1355         this->mwindow = mwindow;
1356         set_tooltip(_("Right justify"));
1357 }
1358 int CWindowProjectorRight::handle_event()
1359 {
1360         FloatAuto *x_auto = 0;
1361         FloatAuto *z_auto = 0;
1362         Track *track = mwindow->cwindow->calculate_affected_track();
1363         if(track)
1364         {
1365                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1366                         0,
1367                         &z_auto,
1368                         track,
1369                         0,
1370                         1,
1371                         0,
1372                         0);
1373         }
1374
1375         if(x_auto && z_auto)
1376         {
1377                 mwindow->undo->update_undo_before(_("projector"), 0);
1378                 x_auto->value = -((double)track->track_w * z_auto->value / 2 - 
1379                         (double)mwindow->edl->session->output_w / 2);
1380                 gui->update();
1381                 gui->update_preview();
1382                 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1383         }
1384
1385         return 1;
1386 }
1387
1388
1389 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1390  : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1391 {
1392         this->gui = gui;
1393         this->mwindow = mwindow;
1394         set_tooltip(_("Top justify"));
1395 }
1396 int CWindowProjectorTop::handle_event()
1397 {
1398         FloatAuto *y_auto = 0;
1399         FloatAuto *z_auto = 0;
1400         Track *track = mwindow->cwindow->calculate_affected_track();
1401         if(track)
1402         {
1403                 mwindow->cwindow->calculate_affected_autos(0,
1404                         &y_auto,
1405                         &z_auto,
1406                         track,
1407                         0,
1408                         0,
1409                         1,
1410                         0);
1411         }
1412
1413         if(y_auto && z_auto)
1414         {
1415                 mwindow->undo->update_undo_before(_("projector"), 0);
1416                 y_auto->value = (double)track->track_h * z_auto->value / 2 - 
1417                         (double)mwindow->edl->session->output_h / 2;
1418                 gui->update();
1419                 gui->update_preview();
1420                 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1421         }
1422
1423         return 1;
1424 }
1425
1426
1427 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1428  : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1429 {
1430         this->gui = gui;
1431         this->mwindow = mwindow;
1432         set_tooltip(_("Center vertical"));
1433 }
1434 int CWindowProjectorMiddle::handle_event()
1435 {
1436         FloatAuto *y_auto = 0;
1437         Track *track = mwindow->cwindow->calculate_affected_track();
1438         if(track)
1439                 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1440                         track->automation->autos[AUTOMATION_PROJECTOR_Y], 1);
1441
1442         if(y_auto)
1443         {
1444                 mwindow->undo->update_undo_before(_("projector"), 0);
1445                 y_auto->value = 0;
1446                 gui->update();
1447                 gui->update_preview();
1448                 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1449         }
1450
1451         return 1;
1452 }
1453
1454
1455 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1456  : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1457 {
1458         this->gui = gui;
1459         this->mwindow = mwindow;
1460         set_tooltip(_("Bottom justify"));
1461 }
1462 int CWindowProjectorBottom::handle_event()
1463 {
1464         FloatAuto *y_auto = 0;
1465         FloatAuto *z_auto = 0;
1466         Track *track = mwindow->cwindow->calculate_affected_track();
1467         if(track)
1468         {
1469                 mwindow->cwindow->calculate_affected_autos(0,
1470                         &y_auto,
1471                         &z_auto,
1472                         track,
1473                         0,
1474                         0,
1475                         1,
1476                         0);
1477         }
1478
1479         if(y_auto && z_auto)
1480         {
1481                 mwindow->undo->update_undo_before(_("projector"), 0);
1482                 y_auto->value = -((double)track->track_h * z_auto->value / 2 - 
1483                         (double)mwindow->edl->session->output_h / 2);
1484                 gui->update();
1485                 gui->update_preview();
1486                 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1487         }
1488
1489         return 1;
1490 }
1491
1492
1493
1494
1495
1496
1497
1498
1499 CWindowMaskMode::CWindowMaskMode(MWindow *mwindow, 
1500         CWindowToolGUI *gui, 
1501         int x, 
1502         int y,
1503         const char *text)
1504  : BC_PopupMenu(x,
1505         y,
1506         200,
1507         text,
1508         1)
1509 {
1510         this->mwindow = mwindow;
1511         this->gui = gui;
1512 }
1513
1514 void CWindowMaskMode::create_objects()
1515 {
1516         add_item(new BC_MenuItem(mode_to_text(MASK_MULTIPLY_ALPHA)));
1517         add_item(new BC_MenuItem(mode_to_text(MASK_SUBTRACT_ALPHA)));
1518 }
1519
1520 char* CWindowMaskMode::mode_to_text(int mode)
1521 {
1522         switch(mode)
1523         {
1524                 case MASK_MULTIPLY_ALPHA:
1525                         return _("Multiply alpha");
1526                         break;
1527                 
1528                 case MASK_SUBTRACT_ALPHA:
1529                         return _("Subtract alpha");
1530                         break;
1531         }
1532
1533         return _("Subtract alpha");
1534 }
1535
1536 int CWindowMaskMode::text_to_mode(char *text)
1537 {
1538         if(!strcasecmp(text, _("Multiply alpha")))
1539                 return MASK_MULTIPLY_ALPHA;
1540         else
1541         if(!strcasecmp(text, _("Subtract alpha")))
1542                 return MASK_SUBTRACT_ALPHA;
1543
1544         return MASK_SUBTRACT_ALPHA;
1545 }
1546
1547 int CWindowMaskMode::handle_event()
1548 {
1549         MaskAutos *autos;
1550         MaskAuto *keyframe;
1551         Track *track;
1552         MaskPoint *point;
1553         SubMask *mask;
1554 // Get existing keyframe
1555         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1556                 autos,
1557                 keyframe, 
1558                 mask,
1559                 point,
1560                 0);
1561         if(track)
1562         {
1563                 mwindow->undo->update_undo_before(_("mask mode"), 0);
1564 #ifdef USE_KEYFRAME_SPANNING
1565 // Create temp keyframe
1566                 MaskAuto temp_keyframe(mwindow->edl, autos);
1567                 temp_keyframe.copy_data(keyframe);
1568 // Update parameter
1569                 temp_keyframe.mode = text_to_mode(get_text());
1570 // Commit change to span of keyframes
1571                 autos->update_parameter(&temp_keyframe);
1572 #else
1573                 ((MaskAuto*)autos->default_auto)->mode = 
1574                         text_to_mode(get_text());
1575 #endif
1576                 mwindow->undo->update_undo_after(_("mask mode"), LOAD_AUTOMATION);
1577         }
1578
1579 //printf("CWindowMaskMode::handle_event 1\n");
1580         gui->update_preview();
1581         return 1;
1582 }
1583
1584
1585
1586
1587
1588
1589
1590
1591 CWindowMaskDelete::CWindowMaskDelete(MWindow *mwindow, 
1592         CWindowToolGUI *gui, 
1593         int x, 
1594         int y)
1595  : BC_GenericButton(x, y, _("Delete"))
1596 {
1597         this->mwindow = mwindow;
1598         this->gui = gui;
1599 }
1600
1601 int CWindowMaskDelete::handle_event()
1602 {
1603         MaskAutos *autos;
1604         MaskAuto *keyframe;
1605         Track *track;
1606         MaskPoint *point;
1607         SubMask *mask;
1608
1609 // Get existing keyframe
1610         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1611                 autos,
1612                 keyframe, 
1613                 mask,
1614                 point,
1615                 0);
1616
1617         if(track)
1618         {
1619                 mwindow->undo->update_undo_before(_("mask delete"), 0);
1620
1621 #ifdef USE_KEYFRAME_SPANNING
1622 // Create temp keyframe
1623                 MaskAuto temp_keyframe(mwindow->edl, autos);
1624                 temp_keyframe.copy_data(keyframe);
1625 // Update parameter
1626                 SubMask *submask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
1627                 for(int i = mwindow->cwindow->gui->affected_point;
1628                         i < submask->points.total - 1;
1629                         i++)
1630                 {
1631                         *submask->points.values[i] = *submask->points.values[i + 1];
1632                 }
1633
1634                 if(submask->points.total)
1635                 {
1636                         submask->points.remove_object(
1637                                 submask->points.values[submask->points.total - 1]);
1638                 }
1639 // Commit change to span of keyframes
1640                 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->update_parameter(&temp_keyframe);
1641 #else
1642                 for(MaskAuto *current = (MaskAuto*)autos->default_auto;
1643                         current; )
1644                 {
1645                         SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1646
1647
1648                         
1649                         for(int i = mwindow->cwindow->gui->affected_point;
1650                                 i < submask->points.total - 1;
1651                                 i++)
1652                         {
1653                                 *submask->points.values[i] = *submask->points.values[i + 1];
1654                         }
1655
1656                         if(submask->points.total)
1657                         {
1658                                 submask->points.remove_object(
1659                                         submask->points.values[submask->points.total - 1]);
1660                         }
1661
1662
1663                         if(current == (MaskAuto*)autos->default_auto)
1664                                 current = (MaskAuto*)autos->first;
1665                         else
1666                                 current = (MaskAuto*)NEXT;
1667                 }
1668 #endif
1669
1670                 gui->update();
1671                 gui->update_preview();
1672                 mwindow->undo->update_undo_after(_("mask delete"), LOAD_AUTOMATION);
1673         }
1674
1675
1676         return 1;
1677 }
1678
1679 int CWindowMaskDelete::keypress_event()
1680 {
1681         if(get_keypress() == BACKSPACE ||
1682                 get_keypress() == DELETE) 
1683                 return handle_event();
1684         return 0;
1685 }
1686
1687
1688 // CWindowMaskCycleNext::CWindowMaskCycleNext(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1689 //  : BC_GenericButton(x, y, _("Cycle next"))
1690 // {
1691 //      this->mwindow = mwindow;
1692 //      this->gui = gui;
1693 // }
1694 // int CWindowMaskCycleNext::handle_event()
1695 // {
1696 //      MaskAuto *keyframe;
1697 //      Track *track;
1698 //      MaskPoint *point;
1699 //      SubMask *mask;
1700 //      ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1701 //              keyframe,
1702 //              mask,  
1703 //              point,
1704 //              0);
1705 // 
1706 //      MaskPoint *temp;
1707 // 
1708 // // Should apply to all keyframes
1709 //      if(keyframe && mask->points.total)
1710 //      {
1711 //              temp = mask->points.values[0];
1712 // 
1713 //              for(int i = 0; i < mask->points.total - 1; i++)
1714 //              {
1715 //                      mask->points.values[i] = mask->points.values[i + 1];
1716 //              }
1717 //              mask->points.values[mask->points.total - 1] = temp;
1718 // 
1719 //              mwindow->cwindow->gui->affected_point--;
1720 //              if(mwindow->cwindow->gui->affected_point < 0)
1721 //                      mwindow->cwindow->gui->affected_point = mask->points.total - 1;
1722 // 
1723 //              gui->update();
1724 //              gui->update_preview();
1725 //      }
1726 //      
1727 //      return 1;
1728 // }
1729 // 
1730 // CWindowMaskCyclePrev::CWindowMaskCyclePrev(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1731 //  : BC_GenericButton(x, y, _("Cycle prev"))
1732 // {
1733 //      this->mwindow = mwindow;
1734 //      this->gui = gui;
1735 // }
1736 // int CWindowMaskCyclePrev::handle_event()
1737 // {
1738 //      MaskAuto *keyframe;
1739 //      Track *track;
1740 //      MaskPoint *point;
1741 //      SubMask *mask;
1742 //      ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1743 //              keyframe,
1744 //              mask, 
1745 //              point,
1746 //              0);
1747 // 
1748 // // Should apply to all keyframes
1749 //      MaskPoint *temp;
1750 //      if(keyframe && mask->points.total)
1751 //      {
1752 //              temp = mask->points.values[mask->points.total - 1];
1753 // 
1754 //              for(int i = mask->points.total - 1; i > 0; i--)
1755 //              {
1756 //                      mask->points.values[i] = mask->points.values[i - 1];
1757 //              }
1758 //              mask->points.values[0] = temp;
1759 // 
1760 //              mwindow->cwindow->gui->affected_point++;
1761 //              if(mwindow->cwindow->gui->affected_point >= mask->points.total)
1762 //                      mwindow->cwindow->gui->affected_point = 0;
1763 // 
1764 //              gui->update();
1765 //              gui->update_preview();
1766 //      }
1767 //      return 1;
1768 // }
1769
1770
1771 CWindowMaskNumber::CWindowMaskNumber(MWindow *mwindow, 
1772         CWindowToolGUI *gui, 
1773         int x, 
1774         int y)
1775  : BC_TumbleTextBox(gui, 
1776                 (int64_t)mwindow->edl->session->cwindow_mask,
1777                 (int64_t)0,
1778                 (int64_t)SUBMASKS - 1,
1779                 x, 
1780                 y, 
1781                 100)
1782 {
1783         this->mwindow = mwindow;
1784         this->gui = gui;
1785 }
1786
1787 CWindowMaskNumber::~CWindowMaskNumber()
1788 {
1789 }
1790
1791 int CWindowMaskNumber::handle_event()
1792 {
1793         mwindow->edl->session->cwindow_mask = atol(get_text());
1794         gui->update();
1795         gui->update_preview();
1796         return 1;
1797 }
1798
1799
1800
1801
1802
1803 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1804  : BC_TumbleTextBox(gui, 
1805                 (int64_t)0,
1806                 (int64_t)0,
1807                 (int64_t)0xff,
1808                 x, 
1809                 y, 
1810                 100)
1811 {
1812         this->mwindow = mwindow;
1813         this->gui = gui;
1814 }
1815 CWindowMaskFeather::~CWindowMaskFeather()
1816 {
1817 }
1818 int CWindowMaskFeather::handle_event()
1819 {
1820         MaskAutos *autos;
1821         MaskAuto *keyframe;
1822         Track *track;
1823         MaskPoint *point;
1824         SubMask *mask;
1825
1826         mwindow->undo->update_undo_before(_("mask feather"), this);
1827
1828 // Get existing keyframe
1829         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1830                 autos,
1831                 keyframe,
1832                 mask, 
1833                 point,
1834 #ifdef USE_KEYFRAME_SPANNING
1835                 0);
1836 #else
1837                 1);
1838 #endif
1839
1840         if(track)
1841         {       
1842 #ifdef USE_KEYFRAME_SPANNING
1843 // Create temp keyframe
1844                 MaskAuto temp_keyframe(mwindow->edl, autos);
1845                 temp_keyframe.copy_data(keyframe);
1846 // Update parameter
1847                 temp_keyframe.feather = atof(get_text());
1848 // Commit change to span of keyframes
1849                 autos->update_parameter(&temp_keyframe);
1850 #else
1851                 keyframe->feather = atof(get_text());
1852 #endif
1853
1854                 gui->update_preview();
1855         }
1856
1857         mwindow->undo->update_undo_after(_("mask feather"), LOAD_AUTOMATION);
1858         return 1;
1859 }
1860
1861 CWindowMaskValue::CWindowMaskValue(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1862  : BC_ISlider(x, 
1863                         y,
1864                         0,
1865                         200, 
1866                         200, 
1867                         0, 
1868                         100, 
1869                         0)
1870 {
1871         this->mwindow = mwindow;
1872         this->gui = gui;
1873 }
1874
1875 CWindowMaskValue::~CWindowMaskValue()
1876 {
1877 }
1878
1879 int CWindowMaskValue::handle_event()
1880 {
1881         MaskAutos *autos;
1882         MaskAuto *keyframe;
1883         Track *track;
1884         MaskPoint *point;
1885         SubMask *mask;
1886         
1887         mwindow->undo->update_undo_before(_("mask value"), this);
1888         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1889                 autos,
1890                 keyframe,
1891                 mask, 
1892                 point,
1893 #ifdef USE_KEYFRAME_SPANNING
1894                 0);
1895 #else
1896                 1);
1897 #endif
1898
1899         if(track)
1900         {
1901 #ifdef USE_KEYFRAME_SPANNING
1902 // Create temp keyframe
1903                 MaskAuto temp_keyframe(mwindow->edl, autos);
1904                 temp_keyframe.copy_data(keyframe);
1905 // Update parameter
1906                 temp_keyframe.value = get_value();
1907 // Commit change to span of keyframes
1908                 autos->update_parameter(&temp_keyframe);
1909 #else
1910                 keyframe->value = get_value();
1911 #endif
1912         }
1913
1914         gui->update_preview();
1915         mwindow->undo->update_undo_after(_("mask value"), LOAD_AUTOMATION);
1916         return 1;
1917 }
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
1930  : CWindowToolGUI(mwindow, 
1931         thread,
1932         _(PROGRAM_NAME ": Mask"),
1933         330,
1934         280)
1935 {
1936         this->mwindow = mwindow;
1937         this->thread = thread;
1938 }
1939 CWindowMaskGUI::~CWindowMaskGUI()
1940 {
1941         lock_window("CWindowMaskGUI::~CWindowMaskGUI");
1942         delete number;
1943         delete feather;
1944         unlock_window();
1945 }
1946
1947 void CWindowMaskGUI::create_objects()
1948 {
1949         int x = 10, y = 10, margin = mwindow->theme->widget_border;
1950         //MaskAuto *keyframe = 0;
1951         //Track *track = mwindow->cwindow->calculate_affected_track();
1952         //if(track)
1953         //      keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], 0);
1954
1955         lock_window("CWindowMaskGUI::create_objects");
1956         BC_Title *title;
1957         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
1958         add_subwindow(mode = new CWindowMaskMode(mwindow, 
1959                 this, 
1960                 x + title->get_w() + margin, 
1961                 y,
1962                 ""));
1963         mode->create_objects();
1964         y += mode->get_h() + margin;
1965         add_subwindow(title = new BC_Title(x, y, _("Value:")));
1966         add_subwindow(value = new CWindowMaskValue(mwindow, this, x + title->get_w() + margin, y));
1967         y += value->get_h() + margin;
1968         add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
1969         y += delete_point->get_h() + margin;
1970         add_subwindow(title = new BC_Title(x, y, _("Mask number:")));
1971         number = new CWindowMaskNumber(mwindow, 
1972                 this, 
1973                 x + title->get_w() + margin, 
1974                 y);
1975         number->create_objects();
1976         y += number->get_h() + margin;
1977         add_subwindow(title = new BC_Title(x, y, _("Feather:")));
1978         feather = new CWindowMaskFeather(mwindow,
1979                 this,
1980                 x + title->get_w() + margin,
1981                 y);
1982         feather->create_objects();
1983         y += feather->get_h() + margin;
1984         add_subwindow(title = new BC_Title(x, y, _("X:")));
1985         x += title->get_w() + margin;
1986         this->x = new CWindowCoord(this, 
1987                 x, 
1988                 y, 
1989                 (float)0.0);
1990         this->x->create_objects();
1991         x += this->x->get_w() + margin;
1992         add_subwindow(title = new BC_Title(x, y, _("Y:")));
1993         x += title->get_w() + margin;
1994         this->y = new CWindowCoord(this, 
1995                 x, 
1996                 y, 
1997                 (float)0.0);
1998         this->y->create_objects();
1999         
2000         x = 10;
2001         y += this->y->get_h() + margin;
2002         add_subwindow(title = new BC_Title(x, y, _("Press Ctrl to move a point")));
2003         y += title->get_h() + margin;
2004         add_subwindow(title = new BC_Title(x, y, _("Press Alt to translate the mask")));
2005         y += title->get_h() + margin;
2006         add_subwindow(title = new BC_Title(x, y, _("Press Shift to edit bezier curve")));
2007
2008         update();
2009         unlock_window();
2010 }
2011
2012 void CWindowMaskGUI::get_keyframe(Track* &track, 
2013         MaskAutos* &autos,
2014         MaskAuto* &keyframe, 
2015         SubMask* &mask, 
2016         MaskPoint* &point,
2017         int create_it)
2018 {
2019         autos = 0;
2020         keyframe = 0;
2021
2022         track = mwindow->cwindow->calculate_affected_track();
2023         if(track)
2024         {
2025                 autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
2026                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(
2027                         autos, 
2028                         create_it);
2029         }
2030
2031         if(keyframe)
2032                 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
2033         else
2034                 mask = 0;
2035
2036         point = 0;
2037         if(keyframe)
2038         {
2039                 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2040                         mwindow->cwindow->gui->affected_point >= 0)
2041                 {
2042                         point = mask->points.values[mwindow->cwindow->gui->affected_point];
2043                 }
2044         }
2045 }
2046
2047 void CWindowMaskGUI::update()
2048 {
2049         MaskAutos *autos;
2050         MaskAuto *keyframe;
2051         Track *track;
2052         MaskPoint *point;
2053         SubMask *mask;
2054 //printf("CWindowMaskGUI::update 1\n");
2055         get_keyframe(track, 
2056                 autos,
2057                 keyframe, 
2058                 mask,
2059                 point,
2060                 0);
2061
2062         double position = mwindow->edl->local_session->get_selectionstart(1);
2063         position = mwindow->edl->align_to_frame(position, 0);
2064         if(track)
2065         {
2066                 int64_t position_i = track->to_units(position, 0);
2067
2068                 if(point)
2069                 {
2070                         x->update(point->x);
2071                         y->update(point->y);
2072                 }
2073
2074                 if(mask)
2075                 {
2076                         feather->update((int64_t)autos->get_feather(position_i, PLAY_FORWARD));
2077                         value->update((int64_t)autos->get_value(position_i, PLAY_FORWARD));
2078                 }
2079         }
2080 //printf("CWindowMaskGUI::update 1\n");
2081
2082         number->update((int64_t)mwindow->edl->session->cwindow_mask);
2083
2084 //printf("CWindowMaskGUI::update 1\n");
2085         if(track)
2086         {
2087 #ifdef USE_KEYFRAME_SPANNING
2088                 mode->set_text(
2089                         CWindowMaskMode::mode_to_text(keyframe->mode));
2090 #else
2091                 mode->set_text(
2092                         CWindowMaskMode::mode_to_text(((MaskAuto*)autos->default_auto)->mode));
2093 #endif
2094         }
2095 //printf("CWindowMaskGUI::update 2\n");
2096 }
2097
2098 void CWindowMaskGUI::handle_event()
2099 {
2100         MaskAutos *autos;
2101         MaskAuto *keyframe;
2102         Track *track;
2103         MaskPoint *point;
2104         SubMask *mask;
2105         get_keyframe(track, 
2106                 autos,
2107                 keyframe, 
2108                 mask,
2109                 point,
2110                 0);
2111
2112         mwindow->undo->update_undo_before(_("mask point"), this);
2113
2114         if(point)
2115         {
2116 #ifdef USE_KEYFRAME_SPANNING
2117 // Create temp keyframe
2118                 MaskAuto temp_keyframe(mwindow->edl, autos);
2119                 temp_keyframe.copy_data(keyframe);
2120 // Get affected point in temp keyframe
2121                 mask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
2122                 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2123                         mwindow->cwindow->gui->affected_point >= 0)
2124                 {
2125                         point = mask->points.values[mwindow->cwindow->gui->affected_point];
2126                 }
2127
2128                 if(point)
2129                 {
2130                         point->x = atof(x->get_text());
2131                         point->y = atof(y->get_text());
2132 // Commit to spanned keyframes
2133                         autos->update_parameter(&temp_keyframe);
2134                 }
2135 #else
2136                 point->x = atof(x->get_text());
2137                 point->y = atof(y->get_text());
2138 #endif
2139         }
2140
2141         update_preview();
2142         mwindow->undo->update_undo_after(_("mask point"), LOAD_AUTOMATION);
2143 }
2144
2145 void CWindowMaskGUI::update_preview()
2146 {
2147         mwindow->restart_brender();
2148         mwindow->sync_parameters(CHANGE_PARAMS);
2149         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
2150                         CHANGE_NONE,
2151                         mwindow->edl,
2152                         1);
2153         mwindow->cwindow->gui->lock_window("CWindowMaskGUI::update_preview");
2154         mwindow->cwindow->gui->canvas->draw_refresh();
2155         mwindow->cwindow->gui->unlock_window();
2156 }
2157
2158
2159
2160
2161
2162
2163
2164
2165 CWindowRulerGUI::CWindowRulerGUI(MWindow *mwindow, CWindowTool *thread)
2166  : CWindowToolGUI(mwindow, 
2167         thread,
2168         _(PROGRAM_NAME ": Ruler"),
2169         320,
2170         240)
2171 {
2172 }
2173
2174 CWindowRulerGUI::~CWindowRulerGUI()
2175 {
2176 }
2177
2178 void CWindowRulerGUI::create_objects()
2179 {
2180         int x = 10, y = 10;
2181         BC_Title *title;
2182
2183         lock_window("CWindowRulerGUI::create_objects");
2184         add_subwindow(title = new BC_Title(x, y, _("Current:")));
2185         add_subwindow(current = new BC_Title(x + title->get_w() + 10, y, ""));
2186         y += title->get_h() + 5;
2187         
2188         add_subwindow(title = new BC_Title(x, y, _("Point 1:")));
2189         add_subwindow(point1 = new BC_Title(x + title->get_w() + 10, y, ""));
2190         y += title->get_h() + 5;
2191
2192         add_subwindow(title = new BC_Title(x, y, _("Point 2:")));
2193         add_subwindow(point2 = new BC_Title(x + title->get_w() + 10, y, ""));
2194         y += title->get_h() + 5;
2195
2196         add_subwindow(title = new BC_Title(x, y, _("Distance:")));
2197         add_subwindow(distance = new BC_Title(x + title->get_w() + 10, y, ""));
2198         y += title->get_h() + 5;
2199         add_subwindow(title = new BC_Title(x, y, _("Angle:")));
2200         add_subwindow(angle = new BC_Title(x + title->get_w() + 10, y, ""));
2201         y += title->get_h() + 10;
2202         char string[BCTEXTLEN];
2203         sprintf(string, _("Press Ctrl to lock ruler to the\nnearest 45%c angle."), 0xb0);
2204         add_subwindow(title = new BC_Title(x, 
2205                 y, 
2206                 string));
2207         y += title->get_h() + 10;
2208         sprintf(string, _("Press Alt to translate the ruler."));
2209         add_subwindow(title = new BC_Title(x, 
2210                 y, 
2211                 string));
2212         update();
2213         unlock_window();
2214 }
2215
2216 void CWindowRulerGUI::update()
2217 {
2218         double distance_value = 
2219                 sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) +
2220                 SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1));
2221         double angle_value = atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) /
2222                 (mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) * 
2223                 360 /
2224                 2 / 
2225                 M_PI;
2226
2227         if(EQUIV(distance_value, 0.0)) 
2228         {
2229                 angle_value = 0.0;
2230         }
2231         else
2232         if(angle_value < 0)
2233         {
2234                 angle_value *= -1;
2235         }
2236
2237         char string[BCTEXTLEN];
2238         sprintf(string, "%d, %d", 
2239                 mwindow->session->cwindow_output_x,
2240                 mwindow->session->cwindow_output_y);
2241         current->update(string);
2242         sprintf(string, "%.0f, %.0f", 
2243                 mwindow->edl->session->ruler_x1,
2244                 mwindow->edl->session->ruler_y1);
2245         point1->update(string);
2246         sprintf(string, "%.0f, %.0f", 
2247                 mwindow->edl->session->ruler_x2,
2248                 mwindow->edl->session->ruler_y2);
2249         point2->update(string);
2250
2251         sprintf(string, _("%0.01f pixels"), distance_value);
2252         distance->update(string);
2253         sprintf(string, "%0.02f %c", angle_value, 0xb0);
2254         angle->update(string);
2255 }
2256
2257 void CWindowRulerGUI::handle_event()
2258 {
2259 }
2260
2261
2262
2263