r999: maintainers added to README_en.
[cinelerra_cv/mob.git] / cinelerra / cwindowtool.C
blob5eb8aa9e87d4aed7ddc49640c267c39dffe524db
1 #include "automation.h"
2 #include "clip.h"
3 #include "condition.h"
4 #include "cpanel.h"
5 #include "cplayback.h"
6 #include "cwindow.h"
7 #include "cwindowgui.h"
8 #include "cwindowtool.h"
9 #include "edl.h"
10 #include "edlsession.h"
11 #include "floatauto.h"
12 #include "floatautos.h"
13 #include "keys.h"
14 #include "language.h"
15 #include "localsession.h"
16 #include "mainsession.h"
17 #include "maskauto.h"
18 #include "maskautos.h"
19 #include "mutex.h"
20 #include "mwindow.h"
21 #include "mwindowgui.h"
22 #include "theme.h"
23 #include "track.h"
24 #include "trackcanvas.h"
25 #include "transportque.h"
28 CWindowTool::CWindowTool(MWindow *mwindow, CWindowGUI *gui)
29  : Thread()
31         this->mwindow = mwindow;
32         this->gui = gui;
33         tool_gui = 0;
34         done = 0;
35         current_tool = CWINDOW_NONE;
36         set_synchronous(1);
37         input_lock = new Condition(0, "CWindowTool::input_lock");
38         output_lock = new Condition(1, "CWindowTool::output_lock");
39         tool_gui_lock = new Mutex("CWindowTool::tool_gui_lock");
42 CWindowTool::~CWindowTool()
44         done = 1;
45         stop_tool();
46         input_lock->unlock();
47         Thread::join();
48         delete input_lock;
49         delete output_lock;
50         delete tool_gui_lock;
53 void CWindowTool::start_tool(int operation)
55         CWindowToolGUI *new_gui = 0;
56         int result = 0;
58 //printf("CWindowTool::start_tool 1\n");
59         if(current_tool != operation)
60         {
61                 current_tool = operation;
62                 switch(operation)
63                 {
64                         case CWINDOW_EYEDROP:
65                                 new_gui = new CWindowEyedropGUI(mwindow, this);
66                                 break;
67                         case CWINDOW_CROP:
68                                 new_gui = new CWindowCropGUI(mwindow, this);
69                                 break;
70                         case CWINDOW_CAMERA:
71                                 new_gui = new CWindowCameraGUI(mwindow, this);
72                                 break;
73                         case CWINDOW_PROJECTOR:
74                                 new_gui = new CWindowProjectorGUI(mwindow, this);
75                                 break;
76                         case CWINDOW_MASK:
77                                 new_gui = new CWindowMaskGUI(mwindow, this);
78                                 break;
79                         default:
80                                 result = 1;
81                                 stop_tool();
82                                 break;
83                 }
85 //printf("CWindowTool::start_tool 1\n");
88                 if(!result)
89                 {
90                         stop_tool();
91 // Wait for previous tool GUI to finish
92                         output_lock->lock("CWindowTool::start_tool");
93                         this->tool_gui = new_gui;
94                         tool_gui->create_objects();
95                         
96                         if(mwindow->edl->session->tool_window &&
97                                 mwindow->session->show_cwindow) tool_gui->show_window();
98                         tool_gui->flush();
99                         
100                         
101 // Signal thread to run next tool GUI
102                         input_lock->unlock();
103                 }
104 //printf("CWindowTool::start_tool 1\n");
105         }
106         else
107         if(tool_gui) 
108         {
109                 tool_gui->lock_window("CWindowTool::start_tool");
110                 tool_gui->update();
111                 tool_gui->unlock_window();
112         }
114 //printf("CWindowTool::start_tool 2\n");
119 void CWindowTool::stop_tool()
121         if(tool_gui)
122         {
123                 tool_gui->lock_window("CWindowTool::stop_tool");
124                 tool_gui->set_done(0);
125                 tool_gui->unlock_window();
126         }
129 void CWindowTool::show_tool()
131         if(tool_gui && mwindow->edl->session->tool_window)
132         {
133                 tool_gui->lock_window("CWindowTool::show_tool");
134                 tool_gui->show_window();
135                 tool_gui->unlock_window();
136         }
139 void CWindowTool::hide_tool()
141         if(tool_gui && mwindow->edl->session->tool_window)
142         {
143                 tool_gui->lock_window("CWindowTool::show_tool");
144                 tool_gui->hide_window();
145                 tool_gui->unlock_window();
146         }
150 void CWindowTool::run()
152         while(!done)
153         {
154                 input_lock->lock("CWindowTool::run");
155                 if(!done)
156                 {
157                         tool_gui->run_window();
158                         tool_gui_lock->lock("CWindowTool::run");
159                         delete tool_gui;
160                         tool_gui = 0;
161                         tool_gui_lock->unlock();
162                 }
163                 output_lock->unlock();
164         }
167 void CWindowTool::update_show_window()
169         if(tool_gui)
170         {
171                 tool_gui->lock_window("CWindowTool::update_show_window");
173                 if(mwindow->edl->session->tool_window) 
174                 {
175                         tool_gui->update();
176                         tool_gui->show_window();
177                 }
178                 else
179                         tool_gui->hide_window();
180                 tool_gui->flush();
182                 tool_gui->unlock_window();
183         }
186 void CWindowTool::update_values()
188         tool_gui_lock->lock("CWindowTool::update_values");
189         if(tool_gui)
190         {
191                 tool_gui->lock_window("CWindowTool::update_values");
192                 tool_gui->update();
193                 tool_gui->flush();
194                 tool_gui->unlock_window();
195         }
196         tool_gui_lock->unlock();
205 CWindowToolGUI::CWindowToolGUI(MWindow *mwindow, 
206         CWindowTool *thread, 
207         char *title,
208         int w, 
209         int h)
210  : BC_Window(title,
211         mwindow->session->ctool_x,
212         mwindow->session->ctool_y,
213         w,
214         h,
215         w,
216         h,
217         0,
218         0,
219         1)
221         this->mwindow = mwindow;
222         this->thread = thread;
223         current_operation = 0;
226 CWindowToolGUI::~CWindowToolGUI()
230 int CWindowToolGUI::close_event()
232         hide_window();
233         flush();
234         mwindow->edl->session->tool_window = 0;
235         unlock_window();
239         thread->gui->lock_window("CWindowToolGUI::close_event");
240         thread->gui->composite_panel->set_operation(mwindow->edl->session->cwindow_operation);
241         thread->gui->flush();
242         thread->gui->unlock_window();
244         lock_window("CWindowToolGUI::close_event");
245         return 1;
248 int CWindowToolGUI::keypress_event()
250         if(get_keypress() == 'w' || get_keypress() == 'W')
251                 return close_event();
252         return 0;
255 int CWindowToolGUI::translation_event()
257         mwindow->session->ctool_x = get_x();
258         mwindow->session->ctool_y = get_y();
259         return 0;
267 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value, int log_increment = 0)
268  : BC_TumbleTextBox(gui, 
269                 (float)value,
270                 (float)-65536,
271                 (float)65536,
272                 x, 
273                 y, 
274                 100)
276         this->gui = gui;
277         set_log_floatincrement(log_increment);
280 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
281  : BC_TumbleTextBox(gui, 
282                 (int64_t)value,
283                 (int64_t)-65536,
284                 (int64_t)65536,
285                 x, 
286                 y, 
287                 100)
289         this->gui = gui;
291 int CWindowCoord::handle_event()
293         gui->event_caller = this;
294         gui->handle_event();
295         return 1;
299 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
300  : BC_GenericButton(x, y, _("Do it"))
302         this->mwindow = mwindow;
303         this->gui = gui;
305 int CWindowCropOK::handle_event()
307         mwindow->crop_video();
308         return 1;
312 int CWindowCropOK::keypress_event()
314         if(get_keypress() == 0xd) 
315         {
316                 handle_event();
317                 return 1;
318         }
319         return 0;
328 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
329  : CWindowToolGUI(mwindow, 
330         thread,
331         PROGRAM_NAME ": Crop",
332         330,
333         100)
338 CWindowCropGUI::~CWindowCropGUI()
342 void CWindowCropGUI::create_objects()
344         int x = 10, y = 10;
345         BC_TumbleTextBox *textbox;
346         BC_Title *title;
348         int column1 = 0;
349         int pad = MAX(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1), 
350                 BC_Title::calculate_h(this, "X")) + 5;
351         add_subwindow(title = new BC_Title(x, y, _("X1:")));
352         column1 = MAX(column1, title->get_w());
353         y += pad;
354         add_subwindow(title = new BC_Title(x, y, _("W:")));
355         column1 = MAX(column1, title->get_w());
356         y += pad;
357         add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
359         x += column1 + 5;
360         y = 10;
361         x1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_x1);
362         x1->create_objects();
363         y += pad;
364         width = new CWindowCoord(thread->tool_gui, 
365                 x, 
366                 y, 
367                 mwindow->edl->session->crop_x2 - 
368                         mwindow->edl->session->crop_x1);
369         width->create_objects();
372         x += x1->get_w() + 10;
373         y = 10;
374         int column2 = 0;
375         add_subwindow(title = new BC_Title(x, y, _("Y1:")));
376         column2 = MAX(column2, title->get_w());
377         y += pad;
378         add_subwindow(title = new BC_Title(x, y, _("H:")));
379         column2 = MAX(column2, title->get_w());
380         y += pad;
382         y = 10;
383         x += column2 + 5;
384         y1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_y1);
385         y1->create_objects();
386         y += pad;
387         height = new CWindowCoord(thread->tool_gui, 
388                 x, 
389                 y, 
390                 mwindow->edl->session->crop_y2 - 
391                         mwindow->edl->session->crop_y1);
392         height->create_objects();
395 void CWindowCropGUI::handle_event()
397         int new_x1, new_y1;
398         new_x1 = atol(x1->get_text());
399         new_y1 = atol(y1->get_text());
400         if(new_x1 != mwindow->edl->session->crop_x1)
401         {
402                 mwindow->edl->session->crop_x2 = new_x1 +
403                         mwindow->edl->session->crop_x2 - 
404                         mwindow->edl->session->crop_x1;
405                 mwindow->edl->session->crop_x1 = new_x1;
406         }
407         if(new_y1 != mwindow->edl->session->crop_y1)
408         {
409                 mwindow->edl->session->crop_y2 = new_y1 +
410                         mwindow->edl->session->crop_y2 -
411                         mwindow->edl->session->crop_y1;
412                 mwindow->edl->session->crop_y1 = atol(y1->get_text());
413         }
414         mwindow->edl->session->crop_x2 = atol(width->get_text()) + 
415                 mwindow->edl->session->crop_x1;
416         mwindow->edl->session->crop_y2 = atol(height->get_text()) + 
417                 mwindow->edl->session->crop_y1;
418         update();
419         mwindow->cwindow->gui->lock_window("CWindowCropGUI::handle_event");
420         mwindow->cwindow->gui->canvas->draw_refresh();
421         mwindow->cwindow->gui->unlock_window();
424 void CWindowCropGUI::update()
426         x1->update((int64_t)mwindow->edl->session->crop_x1);
427         y1->update((int64_t)mwindow->edl->session->crop_y1);
428         width->update((int64_t)mwindow->edl->session->crop_x2 - 
429                 mwindow->edl->session->crop_x1);
430         height->update((int64_t)mwindow->edl->session->crop_y2 - 
431                 mwindow->edl->session->crop_y1);
439 CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
440  : CWindowToolGUI(mwindow, 
441         thread,
442         PROGRAM_NAME ": Color",
443         150,
444         150)
448 CWindowEyedropGUI::~CWindowEyedropGUI()
452 void CWindowEyedropGUI::create_objects()
454         int x = 10;
455         int y = 10;
456         int x2 = 70;
457         BC_Title *title1, *title2, *title3;
458         add_subwindow(title1 = new BC_Title(x, y, "Red:"));
459         y += title1->get_h() + 5;
460         add_subwindow(title2 = new BC_Title(x, y, "Green:"));
461         y += title2->get_h() + 5;
462         add_subwindow(title3 = new BC_Title(x, y, "Blue:"));
465         add_subwindow(red = new BC_Title(x2, title1->get_y(), "0"));
466         add_subwindow(green = new BC_Title(x2, title2->get_y(), "0"));
467         add_subwindow(blue = new BC_Title(x2, title3->get_y(), "0"));
469         y = blue->get_y() + blue->get_h() + 5;
470         add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
471         update();       
474 void CWindowEyedropGUI::update()
476         red->update(mwindow->edl->local_session->red);
477         green->update(mwindow->edl->local_session->green);
478         blue->update(mwindow->edl->local_session->blue);
480         int red = (int)(CLIP(mwindow->edl->local_session->red, 0, 1) * 0xff);
481         int green = (int)(CLIP(mwindow->edl->local_session->green, 0, 1) * 0xff);
482         int blue = (int)(CLIP(mwindow->edl->local_session->blue, 0, 1) * 0xff);
483         sample->set_color((red << 16) | (green << 8) | blue);
484         sample->draw_box(0, 0, sample->get_w(), sample->get_h());
485         sample->set_color(BLACK);
486         sample->draw_rectangle(0, 0, sample->get_w(), sample->get_h());
487         sample->flash();
498 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
499  : CWindowToolGUI(mwindow, 
500         thread,
501         PROGRAM_NAME ": Camera",
502         170,
503         170)
506 CWindowCameraGUI::~CWindowCameraGUI()
510 void CWindowCameraGUI::create_objects()
512         int x = 10, y = 10, x1;
513         Track *track = mwindow->cwindow->calculate_affected_track();
514         FloatAuto *x_auto = 0;
515         FloatAuto *y_auto = 0;
516         FloatAuto *z_auto = 0;
517         BC_Title *title;
518         BC_Button *button;
520         if(track)
521         {
522                 mwindow->cwindow->calculate_affected_autos(&x_auto,
523                         &y_auto,
524                         &z_auto,
525                         track,
526                         1,
527                         0,
528                         0,
529                         0);
530         }
532         add_subwindow(title = new BC_Title(x, y, _("X:")));
533         x += title->get_w();
534         this->x = new CWindowCoord(this, 
535                 x, 
536                 y, 
537                 x_auto ? x_auto->value : (float)0);
538         this->x->create_objects();
539         y += 30;
540         x = 10;
541         add_subwindow(title = new BC_Title(x, y, _("Y:")));
542         x += title->get_w();
543         this->y = new CWindowCoord(this, 
544                 x, 
545                 y, 
546                 y_auto ? y_auto->value : (float)0);
547         this->y->create_objects();
548         y += 30;
549         x = 10;
550         add_subwindow(title = new BC_Title(x, y, _("Z:")));
551         x += title->get_w();
552         this->z = new CWindowCoord(this, 
553                 x, 
554                 y, 
555                 z_auto ? z_auto->value : (float)1,
556                 1);
557         this->z->create_objects();
558         this->z->set_boundaries((float).0001, (float)256.0);
560         y += 30;
561         x1 = 10;
562         add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
563         x1 += button->get_w();
564         add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
565         x1 += button->get_w();
566         add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
568         y += button->get_h();
569         x1 = 10;
570         add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
571         x1 += button->get_w();
572         add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
573         x1 += button->get_w();
574         add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
578 void CWindowCameraGUI::update_preview()
580         mwindow->restart_brender();
581         mwindow->sync_parameters(CHANGE_PARAMS);
583         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
584                         CHANGE_NONE,
585                         mwindow->edl,
586                         1);
587         mwindow->cwindow->gui->lock_window("CWindowCameraGUI::update_preview");
588         mwindow->cwindow->gui->canvas->draw_refresh();
589         mwindow->cwindow->gui->unlock_window();
593 void CWindowCameraGUI::handle_event()
595         FloatAuto *x_auto = 0;
596         FloatAuto *y_auto = 0;
597         FloatAuto *z_auto = 0;
598         Track *track = mwindow->cwindow->calculate_affected_track();
599         if(track)
600         {
601                 if(event_caller == x)
602                 {
603                         x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
604                                 track->automation->autos[AUTOMATION_CAMERA_X],
605                                 1);
606                         if(x_auto)
607                         {
608                                 x_auto->value = atof(x->get_text());
609                                 update_preview();
610                         }
611                 }
612                 else
613                 if(event_caller == y)
614                 {
615                         y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
616                                 track->automation->autos[AUTOMATION_CAMERA_Y],
617                                 1);
618                         if(y_auto)
619                         {
620                                 y_auto->value = atof(y->get_text());
621                                 update_preview();
622                         }
623                 }
624                 else
625                 if(event_caller == z)
626                 {
627                         z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
628                                 track->automation->autos[AUTOMATION_CAMERA_Z],
629                                 1);
630                         if(z_auto)
631                         {
632                                 float zoom = atof(z->get_text());
633                                 if(zoom > 10) zoom = 10; 
634                                 else
635                                 if(zoom < 0) zoom = 0;
636         // Doesn't allow user to enter from scratch
637         //              if(zoom != atof(z->get_text())) 
638         //                      z->update(zoom);
640                                 z_auto->value = zoom;
641                                 mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
642                                 mwindow->gui->canvas->draw_overlays();
643                                 mwindow->gui->canvas->flash();
644                                 mwindow->gui->unlock_window();
645                                 update_preview();
646                         }
647                 }
648         }
651 void CWindowCameraGUI::update()
653         FloatAuto *x_auto = 0;
654         FloatAuto *y_auto = 0;
655         FloatAuto *z_auto = 0;
656         Track *track = mwindow->cwindow->calculate_affected_track();
658         if(track)
659         {
660                 mwindow->cwindow->calculate_affected_autos(&x_auto,
661                         &y_auto,
662                         &z_auto,
663                         track,
664                         1,
665                         0,
666                         0,
667                         0);
668         }
670         if(x_auto)
671                 x->update(x_auto->value);
672         if(y_auto)
673                 y->update(y_auto->value);
674         if(z_auto)
675                 z->update(z_auto->value);
678 // BezierAuto* CWindowCameraGUI::get_keyframe()
679 // {
680 //      BezierAuto *keyframe = 0;
681 //      Track *track = mwindow->cwindow->calculate_affected_track();
682 //      if(track)
683 //              keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
684 //                      track->automation->autos[AUTOMATION_CAMERA]);
685 //      return keyframe;
686 // }
690 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
691  : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
693         this->gui = gui;
694         this->mwindow = mwindow;
695         set_tooltip(_("Left justify"));
697 int CWindowCameraLeft::handle_event()
699         FloatAuto *x_auto = 0;
700         FloatAuto *z_auto = 0;
701         Track *track = mwindow->cwindow->calculate_affected_track();
702         if(track)
703         {
704                 mwindow->cwindow->calculate_affected_autos(&x_auto,
705                         0,
706                         &z_auto,
707                         track,
708                         1,
709                         1,
710                         0,
711                         0);
712         }
714         if(x_auto && z_auto)
715         {
716                 int w = 0, h = 0;
717                 track->get_source_dimensions(
718                         mwindow->edl->local_session->get_selectionstart(1),
719                         w,
720                         h);
722                 if(w && h)
723                 {
724                         x_auto->value = 
725                                 (double)track->track_w / z_auto->value / 2 - 
726                                 (double)w / 2;
727                         gui->update();
728                         gui->update_preview();
729                 }
730         }
732         return 1;
736 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
737  : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
739         this->gui = gui;
740         this->mwindow = mwindow;
741         set_tooltip(_("Center horizontal"));
743 int CWindowCameraCenter::handle_event()
745         FloatAuto *x_auto = 0;
746         Track *track = mwindow->cwindow->calculate_affected_track();
747         if(track)
748                 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
749                         track->automation->autos[AUTOMATION_CAMERA_X],
750                         1);
752         if(x_auto)
753         {
754                 x_auto->value = 0;
755                 gui->update();
756                 gui->update_preview();
757         }
759         return 1;
763 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
764  : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
766         this->gui = gui;
767         this->mwindow = mwindow;
768         set_tooltip(_("Right justify"));
770 int CWindowCameraRight::handle_event()
772         FloatAuto *x_auto = 0;
773         FloatAuto *z_auto = 0;
774         Track *track = mwindow->cwindow->calculate_affected_track();
775         if(track)
776         {
777                 mwindow->cwindow->calculate_affected_autos(&x_auto,
778                         0,
779                         &z_auto,
780                         track,
781                         1,
782                         1,
783                         0,
784                         0);
785         }
787         if(x_auto && z_auto)
788         {
789                 int w = 0, h = 0;
790                 track->get_source_dimensions(
791                         mwindow->edl->local_session->get_selectionstart(1),
792                         w,
793                         h);
795                 if(w && h)
796                 {
797                         x_auto->value = -((double)track->track_w / z_auto->value / 2 - 
798                                 (double)w / 2);
799                         gui->update();
800                         gui->update_preview();
801                 }
802         }
804         return 1;
808 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
809  : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
811         this->gui = gui;
812         this->mwindow = mwindow;
813         set_tooltip(_("Top justify"));
815 int CWindowCameraTop::handle_event()
817         FloatAuto *y_auto = 0;
818         FloatAuto *z_auto = 0;
819         Track *track = mwindow->cwindow->calculate_affected_track();
820         if(track)
821         {
822                 mwindow->cwindow->calculate_affected_autos(0,
823                         &y_auto,
824                         &z_auto,
825                         track,
826                         1,
827                         0,
828                         1,
829                         0);
830         }
832         if(y_auto && z_auto)
833         {
834                 int w = 0, h = 0;
835                 track->get_source_dimensions(
836                         mwindow->edl->local_session->get_selectionstart(1),
837                         w,
838                         h);
840                 if(w && h)
841                 {
842                         y_auto->value = (double)track->track_h / z_auto->value / 2 - 
843                                 (double)h / 2;
844                         gui->update();
845                         gui->update_preview();
846                 }
847         }
849         return 1;
853 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
854  : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
856         this->gui = gui;
857         this->mwindow = mwindow;
858         set_tooltip(_("Center vertical"));
860 int CWindowCameraMiddle::handle_event()
862         FloatAuto *y_auto = 0;
863         Track *track = mwindow->cwindow->calculate_affected_track();
864         if(track)
865                 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
866                         track->automation->autos[AUTOMATION_CAMERA_Y], 1);
868         if(y_auto)
869         {
870                 y_auto->value = 0;
871                 gui->update();
872                 gui->update_preview();
873         }
875         return 1;
879 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
880  : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
882         this->gui = gui;
883         this->mwindow = mwindow;
884         set_tooltip(_("Bottom justify"));
886 int CWindowCameraBottom::handle_event()
888         FloatAuto *y_auto = 0;
889         FloatAuto *z_auto = 0;
890         Track *track = mwindow->cwindow->calculate_affected_track();
891         if(track)
892         {
893                 mwindow->cwindow->calculate_affected_autos(0,
894                         &y_auto,
895                         &z_auto,
896                         track,
897                         1,
898                         0,
899                         1,
900                         0);
901         }
903         if(y_auto && z_auto)
904         {
905                 int w = 0, h = 0;
906                 track->get_source_dimensions(
907                         mwindow->edl->local_session->get_selectionstart(1),
908                         w,
909                         h);
911                 if(w && h)
912                 {
913                         y_auto->value = -((double)track->track_h / z_auto->value / 2 - 
914                                 (double)h / 2);
915                         gui->update();
916                         gui->update_preview();
917                 }
918         }
920         return 1;
939 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
940  : CWindowToolGUI(mwindow, 
941         thread,
942         PROGRAM_NAME ": Projector",
943         170,
944         170)
947 CWindowProjectorGUI::~CWindowProjectorGUI()
950 void CWindowProjectorGUI::create_objects()
952         int x = 10, y = 10, x1;
953         Track *track = mwindow->cwindow->calculate_affected_track();
954         FloatAuto *x_auto = 0;
955         FloatAuto *y_auto = 0;
956         FloatAuto *z_auto = 0;
957         BC_Title *title;
958         BC_Button *button;
960         if(track)
961         {
962                 mwindow->cwindow->calculate_affected_autos(&x_auto,
963                         &y_auto,
964                         &z_auto,
965                         track,
966                         0,
967                         0,
968                         0,
969                         0);
970         }
972         add_subwindow(title = new BC_Title(x, y, _("X:")));
973         x += title->get_w();
974         this->x = new CWindowCoord(this, 
975                 x, 
976                 y, 
977                 x_auto ? x_auto->value : (float)0);
978         this->x->create_objects();
979         y += 30;
980         x = 10;
981         add_subwindow(title = new BC_Title(x, y, _("Y:")));
982         x += title->get_w();
983         this->y = new CWindowCoord(this, 
984                 x, 
985                 y, 
986                 y_auto ? y_auto->value : (float)0);
987         this->y->create_objects();
988         y += 30;
989         x = 10;
990         add_subwindow(title = new BC_Title(x, y, _("Z:")));
991         x += title->get_w();
992         this->z = new CWindowCoord(this, 
993                 x, 
994                 y, 
995                 z_auto ? z_auto->value : (float)1,
996                 1);
997         this->z->create_objects();
998         this->z->set_boundaries((float).0001, (float)256.0);
1000         y += 30;
1001         x1 = 10;
1002         add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
1003         x1 += button->get_w();
1004         add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
1005         x1 += button->get_w();
1006         add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
1008         y += button->get_h();
1009         x1 = 10;
1010         add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
1011         x1 += button->get_w();
1012         add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
1013         x1 += button->get_w();
1014         add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
1018 void CWindowProjectorGUI::update_preview()
1020         mwindow->restart_brender();
1021         mwindow->sync_parameters(CHANGE_PARAMS);
1022         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1023                         CHANGE_NONE,
1024                         mwindow->edl,
1025                         1);
1026         mwindow->cwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
1027         mwindow->cwindow->gui->canvas->draw_refresh();
1028         mwindow->cwindow->gui->unlock_window();
1031 void CWindowProjectorGUI::handle_event()
1033         FloatAuto *x_auto = 0;
1034         FloatAuto *y_auto = 0;
1035         FloatAuto *z_auto = 0;
1036         Track *track = mwindow->cwindow->calculate_affected_track();
1038         if(track)
1039         {
1040                 if(event_caller == x)
1041                 {
1042                         x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1043                                 track->automation->autos[AUTOMATION_PROJECTOR_X],
1044                                 1);
1045                         if(x_auto)
1046                         {
1047                                 x_auto->value = atof(x->get_text());
1048                                 update_preview();
1049                         }
1050                 }
1051                 else
1052                 if(event_caller == y)
1053                 {
1054                         y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1055                                 track->automation->autos[AUTOMATION_PROJECTOR_Y],
1056                                 1);
1057                         if(y_auto)
1058                         {
1059                                 y_auto->value = atof(y->get_text());
1060                                 update_preview();
1061                         }
1062                 }
1063                 else
1064                 if(event_caller == z)
1065                 {
1066                         z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1067                                 track->automation->autos[AUTOMATION_PROJECTOR_Z],
1068                                 1);
1069                         if(z_auto)
1070                         {
1071                                 float zoom = atof(z->get_text());
1072                                 if(zoom > 10000) zoom = 10000; 
1073                                 else 
1074                                 if(zoom < 0) zoom = 0;
1075 //                      if (zoom != atof(z->get_text())) 
1076 //                              z->update(zoom);
1077                                 z_auto->value = zoom;
1079                                 mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
1080                                 mwindow->gui->canvas->draw_overlays();
1081                                 mwindow->gui->canvas->flash();
1082                                 mwindow->gui->unlock_window();
1084                                 update_preview();
1085                         }
1086                 }
1087         }
1090 void CWindowProjectorGUI::update()
1092         FloatAuto *x_auto = 0;
1093         FloatAuto *y_auto = 0;
1094         FloatAuto *z_auto = 0;
1095         Track *track = mwindow->cwindow->calculate_affected_track();
1097         if(track)
1098         {
1099                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1100                         &y_auto,
1101                         &z_auto,
1102                         track,
1103                         0,
1104                         0,
1105                         0,
1106                         0);
1107         }
1109         if(x_auto)
1110                 x->update(x_auto->value);
1111         if(y_auto)
1112                 y->update(y_auto->value);
1113         if(z_auto)
1114                 z->update(z_auto->value);
1117 // BezierAuto* CWindowProjectorGUI::get_keyframe()
1118 // {
1119 //      BezierAuto *keyframe = 0;
1120 //      Track *track = mwindow->cwindow->calculate_affected_track();
1121 //      if(track)
1122 //              keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
1123 //                      track->automation->autos[AUTOMATION_PROJECTOR]);
1124 //      return keyframe;
1125 // }
1164 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1165  : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
1167         this->gui = gui;
1168         this->mwindow = mwindow;
1169         set_tooltip(_("Left justify"));
1171 int CWindowProjectorLeft::handle_event()
1173         FloatAuto *x_auto = 0;
1174         FloatAuto *z_auto = 0;
1175         Track *track = mwindow->cwindow->calculate_affected_track();
1176         if(track)
1177         {
1178                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1179                         0,
1180                         &z_auto,
1181                         track,
1182                         0,
1183                         1,
1184                         0,
1185                         0);
1186         }
1187         if(x_auto && z_auto)
1188         {
1189                 x_auto->value = (double)track->track_w * z_auto->value / 2 - 
1190                         (double)mwindow->edl->session->output_w / 2;
1191                 gui->update();
1192                 gui->update_preview();
1193         }
1195         return 1;
1199 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1200  : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
1202         this->gui = gui;
1203         this->mwindow = mwindow;
1204         set_tooltip(_("Center horizontal"));
1206 int CWindowProjectorCenter::handle_event()
1208         FloatAuto *x_auto = 0;
1209         Track *track = mwindow->cwindow->calculate_affected_track();
1210         if(track)
1211                 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1212                         track->automation->autos[AUTOMATION_PROJECTOR_X],
1213                         1);
1215         if(x_auto)
1216         {
1217                 x_auto->value = 0;
1218                 gui->update();
1219                 gui->update_preview();
1220         }
1222         return 1;
1226 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1227  : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
1229         this->gui = gui;
1230         this->mwindow = mwindow;
1231         set_tooltip(_("Right justify"));
1233 int CWindowProjectorRight::handle_event()
1235         FloatAuto *x_auto = 0;
1236         FloatAuto *z_auto = 0;
1237         Track *track = mwindow->cwindow->calculate_affected_track();
1238         if(track)
1239         {
1240                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1241                         0,
1242                         &z_auto,
1243                         track,
1244                         0,
1245                         1,
1246                         0,
1247                         0);
1248         }
1250         if(x_auto && z_auto)
1251         {
1252                 x_auto->value = -((double)track->track_w * z_auto->value / 2 - 
1253                         (double)mwindow->edl->session->output_w / 2);
1254                 gui->update();
1255                 gui->update_preview();
1256         }
1258         return 1;
1262 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1263  : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1265         this->gui = gui;
1266         this->mwindow = mwindow;
1267         set_tooltip(_("Top justify"));
1269 int CWindowProjectorTop::handle_event()
1271         FloatAuto *y_auto = 0;
1272         FloatAuto *z_auto = 0;
1273         Track *track = mwindow->cwindow->calculate_affected_track();
1274         if(track)
1275         {
1276                 mwindow->cwindow->calculate_affected_autos(0,
1277                         &y_auto,
1278                         &z_auto,
1279                         track,
1280                         0,
1281                         0,
1282                         1,
1283                         0);
1284         }
1286         if(y_auto && z_auto)
1287         {
1288                 y_auto->value = (double)track->track_h * z_auto->value / 2 - 
1289                         (double)mwindow->edl->session->output_h / 2;
1290                 gui->update();
1291                 gui->update_preview();
1292         }
1294         return 1;
1298 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1299  : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1301         this->gui = gui;
1302         this->mwindow = mwindow;
1303         set_tooltip(_("Center vertical"));
1305 int CWindowProjectorMiddle::handle_event()
1307         FloatAuto *y_auto = 0;
1308         Track *track = mwindow->cwindow->calculate_affected_track();
1309         if(track)
1310                 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1311                         track->automation->autos[AUTOMATION_PROJECTOR_Y], 1);
1313         if(y_auto)
1314         {
1315                 y_auto->value = 0;
1316                 gui->update();
1317                 gui->update_preview();
1318         }
1320         return 1;
1324 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1325  : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1327         this->gui = gui;
1328         this->mwindow = mwindow;
1329         set_tooltip(_("Bottom justify"));
1331 int CWindowProjectorBottom::handle_event()
1333         FloatAuto *y_auto = 0;
1334         FloatAuto *z_auto = 0;
1335         Track *track = mwindow->cwindow->calculate_affected_track();
1336         if(track)
1337         {
1338                 mwindow->cwindow->calculate_affected_autos(0,
1339                         &y_auto,
1340                         &z_auto,
1341                         track,
1342                         0,
1343                         0,
1344                         1,
1345                         0);
1346         }
1348         if(y_auto && z_auto)
1349         {
1350                 y_auto->value = -((double)track->track_h * z_auto->value / 2 - 
1351                         (double)mwindow->edl->session->output_h / 2);
1352                 gui->update();
1353                 gui->update_preview();
1354         }
1356         return 1;
1366 CWindowMaskMode::CWindowMaskMode(MWindow *mwindow, 
1367         CWindowToolGUI *gui, 
1368         int x, 
1369         int y,
1370         char *text)
1371  : BC_PopupMenu(x,
1372         y,
1373         200,
1374         text,
1375         1)
1377         this->mwindow = mwindow;
1378         this->gui = gui;
1381 void CWindowMaskMode::create_objects()
1383         add_item(new BC_MenuItem(mode_to_text(MASK_MULTIPLY_ALPHA)));
1384         add_item(new BC_MenuItem(mode_to_text(MASK_SUBTRACT_ALPHA)));
1387 char* CWindowMaskMode::mode_to_text(int mode)
1389         switch(mode)
1390         {
1391                 case MASK_MULTIPLY_ALPHA:
1392                         return _("Multiply alpha");
1393                         break;
1394                 
1395                 case MASK_SUBTRACT_ALPHA:
1396                         return _("Subtract alpha");
1397                         break;
1398         }
1400         return _("Subtract alpha");
1403 int CWindowMaskMode::text_to_mode(char *text)
1405         if(!strcasecmp(text, _("Multiply alpha")))
1406                 return MASK_MULTIPLY_ALPHA;
1407         else
1408         if(!strcasecmp(text, _("Subtract alpha")))
1409                 return MASK_SUBTRACT_ALPHA;
1411         return MASK_SUBTRACT_ALPHA;
1414 int CWindowMaskMode::handle_event()
1416         MaskAuto *keyframe;
1417         Track *track;
1418         MaskPoint *point;
1419         SubMask *mask;
1420         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1421                 keyframe, 
1422                 mask,
1423                 point,
1424                 0);
1426         if(track)
1427         {
1428                 ((MaskAuto*)track->automation->autos[AUTOMATION_MASK]->default_auto)->mode = 
1429                         text_to_mode(get_text());
1430         }
1432 //printf("CWindowMaskMode::handle_event 1\n");
1433         gui->update_preview();
1434         return 1;
1444 CWindowMaskDelete::CWindowMaskDelete(MWindow *mwindow, 
1445         CWindowToolGUI *gui, 
1446         int x, 
1447         int y)
1448  : BC_GenericButton(x, y, _("Delete"))
1450         this->mwindow = mwindow;
1451         this->gui = gui;
1454 int CWindowMaskDelete::handle_event()
1456         MaskAuto *keyframe;
1457         Track *track = mwindow->cwindow->calculate_affected_track();
1458         MaskPoint *point;
1459         SubMask *mask;
1462         if(track)
1463         {
1464                 MaskAutos *mask_autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
1465                 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
1466                         current; )
1467                 {
1468                         SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1471                         
1472                         for(int i = mwindow->cwindow->gui->affected_point;
1473                                 i < submask->points.total - 1;
1474                                 i++)
1475                         {
1476                                 *submask->points.values[i] = *submask->points.values[i + 1];
1477                         }
1479                         if(submask->points.total)
1480                         {
1481                                 submask->points.remove_object(
1482                                         submask->points.values[submask->points.total - 1]);
1483                         }
1486                         if(current == (MaskAuto*)mask_autos->default_auto)
1487                                 current = (MaskAuto*)mask_autos->first;
1488                         else
1489                                 current = (MaskAuto*)NEXT;
1490                 }
1491                 gui->update();
1492                 gui->update_preview();
1493         }
1496 //      ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1497 //              keyframe, 
1498 //              mask, 
1499 //              point,
1500 //              0);
1502 // Need to apply to every keyframe
1503         
1504 //      if(keyframe)
1505 //      {
1506 //              for(int i = mwindow->cwindow->gui->affected_point;
1507 //                      i < mask->points.total - 1;
1508 //                      i++)
1509 //              {
1510 //                      *mask->points.values[i] = *mask->points.values[i + 1];
1511 //              }
1512 //              
1513 //              if(mask->points.total)
1514 //              {
1515 //                      mask->points.remove_object(mask->points.values[mask->points.total - 1]);
1516 //              }
1517 // 
1518 //              gui->update();
1519 //              gui->update_preview();
1520 //      }
1522         return 1;
1525 int CWindowMaskDelete::keypress_event()
1527         if(get_keypress() == BACKSPACE ||
1528                 get_keypress() == DELETE) 
1529                 return handle_event();
1530         return 0;
1534 CWindowMaskCycleNext::CWindowMaskCycleNext(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1535  : BC_GenericButton(x, y, _("Cycle next"))
1537         this->mwindow = mwindow;
1538         this->gui = gui;
1540 int CWindowMaskCycleNext::handle_event()
1542         MaskAuto *keyframe;
1543         Track *track;
1544         MaskPoint *point;
1545         SubMask *mask;
1546         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1547                 keyframe,
1548                 mask,  
1549                 point,
1550                 0);
1552         MaskPoint *temp;
1554 // Should apply to all keyframes
1555         if(keyframe && mask->points.total)
1556         {
1557                 temp = mask->points.values[0];
1559                 for(int i = 0; i < mask->points.total - 1; i++)
1560                 {
1561                         mask->points.values[i] = mask->points.values[i + 1];
1562                 }
1563                 mask->points.values[mask->points.total - 1] = temp;
1565                 mwindow->cwindow->gui->affected_point--;
1566                 if(mwindow->cwindow->gui->affected_point < 0)
1567                         mwindow->cwindow->gui->affected_point = mask->points.total - 1;
1569                 gui->update();
1570                 gui->update_preview();
1571         }
1572         
1573         return 1;
1576 CWindowMaskCyclePrev::CWindowMaskCyclePrev(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1577  : BC_GenericButton(x, y, _("Cycle prev"))
1579         this->mwindow = mwindow;
1580         this->gui = gui;
1582 int CWindowMaskCyclePrev::handle_event()
1584         MaskAuto *keyframe;
1585         Track *track;
1586         MaskPoint *point;
1587         SubMask *mask;
1588         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1589                 keyframe,
1590                 mask, 
1591                 point,
1592                 0);
1594 // Should apply to all keyframes
1595         MaskPoint *temp;
1596         if(keyframe && mask->points.total)
1597         {
1598                 temp = mask->points.values[mask->points.total - 1];
1600                 for(int i = mask->points.total - 1; i > 0; i--)
1601                 {
1602                         mask->points.values[i] = mask->points.values[i - 1];
1603                 }
1604                 mask->points.values[0] = temp;
1606                 mwindow->cwindow->gui->affected_point++;
1607                 if(mwindow->cwindow->gui->affected_point >= mask->points.total)
1608                         mwindow->cwindow->gui->affected_point = 0;
1610                 gui->update();
1611                 gui->update_preview();
1612         }
1613         return 1;
1617 CWindowMaskNumber::CWindowMaskNumber(MWindow *mwindow, 
1618         CWindowToolGUI *gui, 
1619         int x, 
1620         int y)
1621  : BC_TumbleTextBox(gui, 
1622                 (int64_t)mwindow->edl->session->cwindow_mask,
1623                 (int64_t)0,
1624                 (int64_t)SUBMASKS - 1,
1625                 x, 
1626                 y, 
1627                 100)
1629         this->mwindow = mwindow;
1630         this->gui = gui;
1633 CWindowMaskNumber::~CWindowMaskNumber()
1637 int CWindowMaskNumber::handle_event()
1639         mwindow->edl->session->cwindow_mask = atol(get_text());
1640         gui->update();
1641         gui->update_preview();
1642         return 1;
1649 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1650  : BC_TumbleTextBox(gui, 
1651                 (int64_t)0,
1652                 (int64_t)0,
1653                 (int64_t)0xff,
1654                 x, 
1655                 y, 
1656                 100)
1658         this->mwindow = mwindow;
1659         this->gui = gui;
1661 CWindowMaskFeather::~CWindowMaskFeather()
1664 int CWindowMaskFeather::handle_event()
1666         MaskAuto *keyframe;
1667         Track *track;
1668         MaskPoint *point;
1669         SubMask *mask;
1670         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1671                 keyframe,
1672                 mask, 
1673                 point,
1674                 1);
1676         keyframe->feather = atof(get_text());
1677         gui->update_preview();
1678         return 1;
1681 CWindowMaskValue::CWindowMaskValue(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1682  : BC_ISlider(x, 
1683                         y,
1684                         0,
1685                         200, 
1686                         200, 
1687                         0, 
1688                         100, 
1689                         0)
1691         this->mwindow = mwindow;
1692         this->gui = gui;
1695 CWindowMaskValue::~CWindowMaskValue()
1699 int CWindowMaskValue::handle_event()
1701         MaskAuto *keyframe;
1702         Track *track;
1703         MaskPoint *point;
1704         SubMask *mask;
1705         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1706                 keyframe,
1707                 mask, 
1708                 point,
1709                 1);
1711         keyframe->value = get_value();
1712         gui->update_preview();
1713         return 1;
1718 CWindowMaskBeforePlugins::CWindowMaskBeforePlugins(CWindowToolGUI *gui, int x, int y)
1719  : BC_CheckBox(x, 
1720         y, 
1721         1, 
1722         _("Apply mask before plugins"))
1724         this->gui = gui;
1727 int CWindowMaskBeforePlugins::handle_event()
1729         MaskAuto *keyframe;
1730         Track *track;
1731         MaskPoint *point;
1732         SubMask *mask;
1733         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1734                 keyframe,
1735                 mask, 
1736                 point,
1737                 1);
1739         keyframe->apply_before_plugins = get_value();
1740         gui->update_preview();
1741         return 1;
1751 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
1752  : CWindowToolGUI(mwindow, 
1753         thread,
1754         PROGRAM_NAME ": Mask",
1755         330,
1756         280)
1758         this->mwindow = mwindow;
1759         this->thread = thread;
1761 CWindowMaskGUI::~CWindowMaskGUI()
1763         delete number;
1764         delete feather;
1767 void CWindowMaskGUI::create_objects()
1769         int x = 10, y = 10;
1770         MaskAuto *keyframe = 0;
1771         Track *track = mwindow->cwindow->calculate_affected_track();
1772         if(track)
1773                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], 0);
1775         BC_Title *title;
1776         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
1777         add_subwindow(mode = new CWindowMaskMode(mwindow, 
1778                 this, 
1779                 x + title->get_w(), 
1780                 y,
1781                 ""));
1782         mode->create_objects();
1783         y += 40;
1784         add_subwindow(new BC_Title(x, y, _("Value:")));
1785         add_subwindow(value = new CWindowMaskValue(mwindow, this, x + 50, y));
1786         y += 30;
1787         add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
1788         y += 30;
1789         add_subwindow(new BC_Title(x, y, _("Mask number:")));
1790         number = new CWindowMaskNumber(mwindow, 
1791                 this, 
1792                 x + 110, 
1793                 y);
1794         number->create_objects();
1795         y += 30;
1796         add_subwindow(new BC_Title(x, y, _("Feather:")));
1797         feather = new CWindowMaskFeather(mwindow,
1798                 this,
1799                 x + 110,
1800                 y);
1801         feather->create_objects();
1802         y += 30;
1803         add_subwindow(title = new BC_Title(x, y, _("X:")));
1804         x += title->get_w();
1805         this->x = new CWindowCoord(this, 
1806                 x, 
1807                 y, 
1808                 (float)0.0);
1809         this->x->create_objects();
1810         x += 150;
1811         add_subwindow(title = new BC_Title(x, y, _("Y:")));
1812         x += title->get_w();
1813         this->y = new CWindowCoord(this, 
1814                 x, 
1815                 y, 
1816                 (float)0.0);
1817         this->y->create_objects();
1819         y += 30;
1820 //      add_subwindow(title = new BC_Title(x, y, _("Apply mask before plugins:")));
1821         
1822         add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this, 
1823                 10, 
1824                 y));
1825 //      this->apply_before_plugins->create_objects();
1828         update();
1831 void CWindowMaskGUI::get_keyframe(Track* &track, 
1832         MaskAuto* &keyframe, 
1833         SubMask* &mask, 
1834         MaskPoint* &point,
1835         int create_it)
1837         keyframe = 0;
1838         track = mwindow->cwindow->calculate_affected_track();
1839         if(track)
1840                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], create_it);
1841         else
1842                 keyframe = 0;
1844         if(keyframe)
1845                 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
1846         else
1847                 mask = 0;
1849         point = 0;
1850         if(keyframe)
1851         {
1852                 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
1853                         mwindow->cwindow->gui->affected_point >= 0)
1854                 {
1855                         point =  mask->points.values[mwindow->cwindow->gui->affected_point];
1856                 }
1857         }
1860 void CWindowMaskGUI::update()
1862         MaskAuto *keyframe;
1863         Track *track;
1864         MaskPoint *point;
1865         SubMask *mask;
1866 //printf("CWindowMaskGUI::update 1\n");
1867         get_keyframe(track, 
1868                 keyframe, 
1869                 mask,
1870                 point,
1871                 0);
1873 //printf("CWindowMaskGUI::update 1\n");
1874         if(point)
1875         {
1876                 x->update(point->x);
1877                 y->update(point->y);
1878         }
1879 //printf("CWindowMaskGUI::update 1\n");
1881         if(mask)
1882         {
1883                 feather->update((int64_t)keyframe->feather);
1884                 value->update((int64_t)keyframe->value);
1885                 apply_before_plugins->update((int64_t)keyframe->apply_before_plugins);
1886         }
1887 //printf("CWindowMaskGUI::update 1\n");
1889         number->update((int64_t)mwindow->edl->session->cwindow_mask);
1891 //printf("CWindowMaskGUI::update 1\n");
1892         if(track)
1893         {
1894                 mode->set_text(
1895                         CWindowMaskMode::mode_to_text(((MaskAuto*)track->automation->autos[AUTOMATION_MASK]->default_auto)->mode));
1896         }
1897 //printf("CWindowMaskGUI::update 2\n");
1900 void CWindowMaskGUI::handle_event()
1902         MaskAuto *keyframe;
1903         Track *track;
1904         MaskPoint *point;
1905         SubMask *mask;
1906         get_keyframe(track, 
1907                 keyframe, 
1908                 mask,
1909                 point,
1910                 0);
1912         if(point)
1913         {
1914                 point->x = atof(x->get_text());
1915                 point->y = atof(y->get_text());
1916         }
1918         update_preview();
1921 void CWindowMaskGUI::update_preview()
1923         mwindow->restart_brender();
1924         mwindow->sync_parameters(CHANGE_PARAMS);
1925         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1926                         CHANGE_NONE,
1927                         mwindow->edl,
1928                         1);
1929         mwindow->cwindow->gui->lock_window("CWindowMaskGUI::update_preview");
1930         mwindow->cwindow->gui->canvas->draw_refresh();
1931         mwindow->cwindow->gui->unlock_window();