r870: Merge 2.1:
[cinelerra_cv.git] / cinelerra / cwindowtool.C
blob006556f822b5f67c354dde8ab72cb99e94dbebf6
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)
268  : BC_TumbleTextBox(gui, 
269                 (float)value,
270                 (float)-65536,
271                 (float)65536,
272                 x, 
273                 y, 
274                 100)
276         this->gui = gui;
279 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
280  : BC_TumbleTextBox(gui, 
281                 (int64_t)value,
282                 (int64_t)-65536,
283                 (int64_t)65536,
284                 x, 
285                 y, 
286                 100)
288         this->gui = gui;
290 int CWindowCoord::handle_event()
292         gui->event_caller = this;
293         gui->handle_event();
294         return 1;
298 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
299  : BC_GenericButton(x, y, _("Do it"))
301         this->mwindow = mwindow;
302         this->gui = gui;
304 int CWindowCropOK::handle_event()
306         mwindow->crop_video();
307         return 1;
311 int CWindowCropOK::keypress_event()
313         if(get_keypress() == 0xd) 
314         {
315                 handle_event();
316                 return 1;
317         }
318         return 0;
327 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
328  : CWindowToolGUI(mwindow, 
329         thread,
330         PROGRAM_NAME ": Crop",
331         330,
332         100)
337 CWindowCropGUI::~CWindowCropGUI()
341 void CWindowCropGUI::create_objects()
343         int x = 10, y = 10;
344         BC_TumbleTextBox *textbox;
345         BC_Title *title;
347         int column1 = 0;
348         int pad = MAX(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1), 
349                 BC_Title::calculate_h(this, "X")) + 5;
350         add_subwindow(title = new BC_Title(x, y, _("X1:")));
351         column1 = MAX(column1, title->get_w());
352         y += pad;
353         add_subwindow(title = new BC_Title(x, y, _("W:")));
354         column1 = MAX(column1, title->get_w());
355         y += pad;
356         add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
358         x += column1 + 5;
359         y = 10;
360         x1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_x1);
361         x1->create_objects();
362         y += pad;
363         width = new CWindowCoord(thread->tool_gui, 
364                 x, 
365                 y, 
366                 mwindow->edl->session->crop_x2 - 
367                         mwindow->edl->session->crop_x1);
368         width->create_objects();
371         x += x1->get_w() + 10;
372         y = 10;
373         int column2 = 0;
374         add_subwindow(title = new BC_Title(x, y, _("Y1:")));
375         column2 = MAX(column2, title->get_w());
376         y += pad;
377         add_subwindow(title = new BC_Title(x, y, _("H:")));
378         column2 = MAX(column2, title->get_w());
379         y += pad;
381         y = 10;
382         x += column2 + 5;
383         y1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_y1);
384         y1->create_objects();
385         y += pad;
386         height = new CWindowCoord(thread->tool_gui, 
387                 x, 
388                 y, 
389                 mwindow->edl->session->crop_y2 - 
390                         mwindow->edl->session->crop_y1);
391         height->create_objects();
394 void CWindowCropGUI::handle_event()
396         int new_x1, new_y1;
397         new_x1 = atol(x1->get_text());
398         new_y1 = atol(y1->get_text());
399         if(new_x1 != mwindow->edl->session->crop_x1)
400         {
401                 mwindow->edl->session->crop_x2 = new_x1 +
402                         mwindow->edl->session->crop_x2 - 
403                         mwindow->edl->session->crop_x1;
404                 mwindow->edl->session->crop_x1 = new_x1;
405         }
406         if(new_y1 != mwindow->edl->session->crop_y1)
407         {
408                 mwindow->edl->session->crop_y2 = new_y1 +
409                         mwindow->edl->session->crop_y2 -
410                         mwindow->edl->session->crop_y1;
411                 mwindow->edl->session->crop_y1 = atol(y1->get_text());
412         }
413         mwindow->edl->session->crop_x2 = atol(width->get_text()) + 
414                 mwindow->edl->session->crop_x1;
415         mwindow->edl->session->crop_y2 = atol(height->get_text()) + 
416                 mwindow->edl->session->crop_y1;
417         update();
418         mwindow->cwindow->gui->lock_window("CWindowCropGUI::handle_event");
419         mwindow->cwindow->gui->canvas->draw_refresh();
420         mwindow->cwindow->gui->unlock_window();
423 void CWindowCropGUI::update()
425         x1->update((int64_t)mwindow->edl->session->crop_x1);
426         y1->update((int64_t)mwindow->edl->session->crop_y1);
427         width->update((int64_t)mwindow->edl->session->crop_x2 - 
428                 mwindow->edl->session->crop_x1);
429         height->update((int64_t)mwindow->edl->session->crop_y2 - 
430                 mwindow->edl->session->crop_y1);
438 CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
439  : CWindowToolGUI(mwindow, 
440         thread,
441         PROGRAM_NAME ": Color",
442         150,
443         150)
447 CWindowEyedropGUI::~CWindowEyedropGUI()
451 void CWindowEyedropGUI::create_objects()
453         int x = 10;
454         int y = 10;
455         int x2 = 70;
456         BC_Title *title1, *title2, *title3;
457         add_subwindow(title1 = new BC_Title(x, y, "Red:"));
458         y += title1->get_h() + 5;
459         add_subwindow(title2 = new BC_Title(x, y, "Green:"));
460         y += title2->get_h() + 5;
461         add_subwindow(title3 = new BC_Title(x, y, "Blue:"));
464         add_subwindow(red = new BC_Title(x2, title1->get_y(), "0"));
465         add_subwindow(green = new BC_Title(x2, title2->get_y(), "0"));
466         add_subwindow(blue = new BC_Title(x2, title3->get_y(), "0"));
468         y = blue->get_y() + blue->get_h() + 5;
469         add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
470         update();       
473 void CWindowEyedropGUI::update()
475         red->update(mwindow->edl->local_session->red);
476         green->update(mwindow->edl->local_session->green);
477         blue->update(mwindow->edl->local_session->blue);
479         int red = (int)(CLIP(mwindow->edl->local_session->red, 0, 1) * 0xff);
480         int green = (int)(CLIP(mwindow->edl->local_session->green, 0, 1) * 0xff);
481         int blue = (int)(CLIP(mwindow->edl->local_session->blue, 0, 1) * 0xff);
482         sample->set_color((red << 16) | (green << 8) | blue);
483         sample->draw_box(0, 0, sample->get_w(), sample->get_h());
484         sample->set_color(BLACK);
485         sample->draw_rectangle(0, 0, sample->get_w(), sample->get_h());
486         sample->flash();
497 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
498  : CWindowToolGUI(mwindow, 
499         thread,
500         PROGRAM_NAME ": Camera",
501         170,
502         170)
505 CWindowCameraGUI::~CWindowCameraGUI()
509 void CWindowCameraGUI::create_objects()
511         int x = 10, y = 10, x1;
512         Track *track = mwindow->cwindow->calculate_affected_track();
513         FloatAuto *x_auto = 0;
514         FloatAuto *y_auto = 0;
515         FloatAuto *z_auto = 0;
516         BC_Title *title;
517         BC_Button *button;
519         if(track)
520         {
521                 mwindow->cwindow->calculate_affected_autos(&x_auto,
522                         &y_auto,
523                         &z_auto,
524                         track,
525                         1,
526                         0,
527                         0,
528                         0);
529         }
531         add_subwindow(title = new BC_Title(x, y, _("X:")));
532         x += title->get_w();
533         this->x = new CWindowCoord(this, 
534                 x, 
535                 y, 
536                 x_auto ? x_auto->value : (float)0);
537         this->x->create_objects();
538         y += 30;
539         x = 10;
540         add_subwindow(title = new BC_Title(x, y, _("Y:")));
541         x += title->get_w();
542         this->y = new CWindowCoord(this, 
543                 x, 
544                 y, 
545                 y_auto ? y_auto->value : (float)0);
546         this->y->create_objects();
547         y += 30;
548         x = 10;
549         add_subwindow(title = new BC_Title(x, y, _("Z:")));
550         x += title->get_w();
551         this->z = new CWindowCoord(this, 
552                 x, 
553                 y, 
554                 z_auto ? z_auto->value : (float)1);
555         this->z->create_objects();
557         y += 30;
558         x1 = 10;
559         add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
560         x1 += button->get_w();
561         add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
562         x1 += button->get_w();
563         add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
565         y += button->get_h();
566         x1 = 10;
567         add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
568         x1 += button->get_w();
569         add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
570         x1 += button->get_w();
571         add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
575 void CWindowCameraGUI::update_preview()
577         mwindow->restart_brender();
578         mwindow->sync_parameters(CHANGE_PARAMS);
580         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
581                         CHANGE_NONE,
582                         mwindow->edl,
583                         1);
584         mwindow->cwindow->gui->lock_window("CWindowCameraGUI::update_preview");
585         mwindow->cwindow->gui->canvas->draw_refresh();
586         mwindow->cwindow->gui->unlock_window();
590 void CWindowCameraGUI::handle_event()
592         FloatAuto *x_auto = 0;
593         FloatAuto *y_auto = 0;
594         FloatAuto *z_auto = 0;
595         Track *track = mwindow->cwindow->calculate_affected_track();
596         if(track)
597         {
598                 if(event_caller == x)
599                 {
600                         x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
601                                 track->automation->autos[AUTOMATION_CAMERA_X],
602                                 1);
603                         if(x_auto)
604                         {
605                                 x_auto->value = atof(x->get_text());
606                                 update_preview();
607                         }
608                 }
609                 else
610                 if(event_caller == y)
611                 {
612                         y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
613                                 track->automation->autos[AUTOMATION_CAMERA_Y],
614                                 1);
615                         if(y_auto)
616                         {
617                                 y_auto->value = atof(y->get_text());
618                                 update_preview();
619                         }
620                 }
621                 else
622                 if(event_caller == z)
623                 {
624                         z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
625                                 track->automation->autos[AUTOMATION_CAMERA_Z],
626                                 1);
627                         if(z_auto)
628                         {
629                                 float zoom = atof(z->get_text());
630                                 if(zoom > 10) zoom = 10; 
631                                 else
632                                 if(zoom < 0) zoom = 0;
633         // Doesn't allow user to enter from scratch
634         //              if(zoom != atof(z->get_text())) 
635         //                      z->update(zoom);
637                                 z_auto->value = zoom;
638                                 mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
639                                 mwindow->gui->canvas->draw_overlays();
640                                 mwindow->gui->canvas->flash();
641                                 mwindow->gui->unlock_window();
642                                 update_preview();
643                         }
644                 }
645         }
648 void CWindowCameraGUI::update()
650         FloatAuto *x_auto = 0;
651         FloatAuto *y_auto = 0;
652         FloatAuto *z_auto = 0;
653         Track *track = mwindow->cwindow->calculate_affected_track();
655         if(track)
656         {
657                 mwindow->cwindow->calculate_affected_autos(&x_auto,
658                         &y_auto,
659                         &z_auto,
660                         track,
661                         1,
662                         0,
663                         0,
664                         0);
665         }
667         if(x_auto)
668                 x->update(x_auto->value);
669         if(y_auto)
670                 y->update(y_auto->value);
671         if(z_auto)
672                 z->update(z_auto->value);
675 // BezierAuto* CWindowCameraGUI::get_keyframe()
676 // {
677 //      BezierAuto *keyframe = 0;
678 //      Track *track = mwindow->cwindow->calculate_affected_track();
679 //      if(track)
680 //              keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
681 //                      track->automation->autos[AUTOMATION_CAMERA]);
682 //      return keyframe;
683 // }
687 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
688  : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
690         this->gui = gui;
691         this->mwindow = mwindow;
692         set_tooltip(_("Left justify"));
694 int CWindowCameraLeft::handle_event()
696         FloatAuto *x_auto = 0;
697         FloatAuto *z_auto = 0;
698         Track *track = mwindow->cwindow->calculate_affected_track();
699         if(track)
700         {
701                 mwindow->cwindow->calculate_affected_autos(&x_auto,
702                         0,
703                         &z_auto,
704                         track,
705                         1,
706                         1,
707                         0,
708                         0);
709         }
711         if(x_auto && z_auto)
712         {
713                 int w = 0, h = 0;
714                 track->get_source_dimensions(
715                         mwindow->edl->local_session->get_selectionstart(1),
716                         w,
717                         h);
719                 if(w && h)
720                 {
721                         x_auto->value = 
722                                 (double)track->track_w / z_auto->value / 2 - 
723                                 (double)w / 2;
724                         gui->update();
725                         gui->update_preview();
726                 }
727         }
729         return 1;
733 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
734  : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
736         this->gui = gui;
737         this->mwindow = mwindow;
738         set_tooltip(_("Center horizontal"));
740 int CWindowCameraCenter::handle_event()
742         FloatAuto *x_auto = 0;
743         Track *track = mwindow->cwindow->calculate_affected_track();
744         if(track)
745                 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
746                         track->automation->autos[AUTOMATION_CAMERA_X],
747                         1);
749         if(x_auto)
750         {
751                 x_auto->value = 0;
752                 gui->update();
753                 gui->update_preview();
754         }
756         return 1;
760 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
761  : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
763         this->gui = gui;
764         this->mwindow = mwindow;
765         set_tooltip(_("Right justify"));
767 int CWindowCameraRight::handle_event()
769         FloatAuto *x_auto = 0;
770         FloatAuto *z_auto = 0;
771         Track *track = mwindow->cwindow->calculate_affected_track();
772         if(track)
773         {
774                 mwindow->cwindow->calculate_affected_autos(&x_auto,
775                         0,
776                         &z_auto,
777                         track,
778                         1,
779                         1,
780                         0,
781                         0);
782         }
784         if(x_auto && z_auto)
785         {
786                 int w = 0, h = 0;
787                 track->get_source_dimensions(
788                         mwindow->edl->local_session->get_selectionstart(1),
789                         w,
790                         h);
792                 if(w && h)
793                 {
794                         x_auto->value = -((double)track->track_w / z_auto->value / 2 - 
795                                 (double)w / 2);
796                         gui->update();
797                         gui->update_preview();
798                 }
799         }
801         return 1;
805 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
806  : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
808         this->gui = gui;
809         this->mwindow = mwindow;
810         set_tooltip(_("Top justify"));
812 int CWindowCameraTop::handle_event()
814         FloatAuto *y_auto = 0;
815         FloatAuto *z_auto = 0;
816         Track *track = mwindow->cwindow->calculate_affected_track();
817         if(track)
818         {
819                 mwindow->cwindow->calculate_affected_autos(0,
820                         &y_auto,
821                         &z_auto,
822                         track,
823                         1,
824                         0,
825                         1,
826                         0);
827         }
829         if(y_auto && z_auto)
830         {
831                 int w = 0, h = 0;
832                 track->get_source_dimensions(
833                         mwindow->edl->local_session->get_selectionstart(1),
834                         w,
835                         h);
837                 if(w && h)
838                 {
839                         y_auto->value = (double)track->track_h / z_auto->value / 2 - 
840                                 (double)h / 2;
841                         gui->update();
842                         gui->update_preview();
843                 }
844         }
846         return 1;
850 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
851  : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
853         this->gui = gui;
854         this->mwindow = mwindow;
855         set_tooltip(_("Center vertical"));
857 int CWindowCameraMiddle::handle_event()
859         FloatAuto *y_auto = 0;
860         Track *track = mwindow->cwindow->calculate_affected_track();
861         if(track)
862                 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
863                         track->automation->autos[AUTOMATION_CAMERA_Y], 1);
865         if(y_auto)
866         {
867                 y_auto->value = 0;
868                 gui->update();
869                 gui->update_preview();
870         }
872         return 1;
876 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
877  : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
879         this->gui = gui;
880         this->mwindow = mwindow;
881         set_tooltip(_("Bottom justify"));
883 int CWindowCameraBottom::handle_event()
885         FloatAuto *y_auto = 0;
886         FloatAuto *z_auto = 0;
887         Track *track = mwindow->cwindow->calculate_affected_track();
888         if(track)
889         {
890                 mwindow->cwindow->calculate_affected_autos(0,
891                         &y_auto,
892                         &z_auto,
893                         track,
894                         1,
895                         0,
896                         1,
897                         0);
898         }
900         if(y_auto && z_auto)
901         {
902                 int w = 0, h = 0;
903                 track->get_source_dimensions(
904                         mwindow->edl->local_session->get_selectionstart(1),
905                         w,
906                         h);
908                 if(w && h)
909                 {
910                         y_auto->value = -((double)track->track_h / z_auto->value / 2 - 
911                                 (double)h / 2);
912                         gui->update();
913                         gui->update_preview();
914                 }
915         }
917         return 1;
936 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
937  : CWindowToolGUI(mwindow, 
938         thread,
939         PROGRAM_NAME ": Projector",
940         170,
941         170)
944 CWindowProjectorGUI::~CWindowProjectorGUI()
947 void CWindowProjectorGUI::create_objects()
949         int x = 10, y = 10, x1;
950         Track *track = mwindow->cwindow->calculate_affected_track();
951         FloatAuto *x_auto = 0;
952         FloatAuto *y_auto = 0;
953         FloatAuto *z_auto = 0;
954         BC_Title *title;
955         BC_Button *button;
957         if(track)
958         {
959                 mwindow->cwindow->calculate_affected_autos(&x_auto,
960                         &y_auto,
961                         &z_auto,
962                         track,
963                         0,
964                         0,
965                         0,
966                         0);
967         }
969         add_subwindow(title = new BC_Title(x, y, _("X:")));
970         x += title->get_w();
971         this->x = new CWindowCoord(this, 
972                 x, 
973                 y, 
974                 x_auto ? x_auto->value : (float)0);
975         this->x->create_objects();
976         y += 30;
977         x = 10;
978         add_subwindow(title = new BC_Title(x, y, _("Y:")));
979         x += title->get_w();
980         this->y = new CWindowCoord(this, 
981                 x, 
982                 y, 
983                 y_auto ? y_auto->value : (float)0);
984         this->y->create_objects();
985         y += 30;
986         x = 10;
987         add_subwindow(title = new BC_Title(x, y, _("Z:")));
988         x += title->get_w();
989         this->z = new CWindowCoord(this, 
990                 x, 
991                 y, 
992                 z_auto ? z_auto->value : (float)1);
993         this->z->create_objects();
995         y += 30;
996         x1 = 10;
997         add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
998         x1 += button->get_w();
999         add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
1000         x1 += button->get_w();
1001         add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
1003         y += button->get_h();
1004         x1 = 10;
1005         add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
1006         x1 += button->get_w();
1007         add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
1008         x1 += button->get_w();
1009         add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
1013 void CWindowProjectorGUI::update_preview()
1015         mwindow->restart_brender();
1016         mwindow->sync_parameters(CHANGE_PARAMS);
1017         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1018                         CHANGE_NONE,
1019                         mwindow->edl,
1020                         1);
1021         mwindow->cwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
1022         mwindow->cwindow->gui->canvas->draw_refresh();
1023         mwindow->cwindow->gui->unlock_window();
1026 void CWindowProjectorGUI::handle_event()
1028         FloatAuto *x_auto = 0;
1029         FloatAuto *y_auto = 0;
1030         FloatAuto *z_auto = 0;
1031         Track *track = mwindow->cwindow->calculate_affected_track();
1033         if(track)
1034         {
1035                 if(event_caller == x)
1036                 {
1037                         x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1038                                 track->automation->autos[AUTOMATION_PROJECTOR_X],
1039                                 1);
1040                         if(x_auto)
1041                         {
1042                                 x_auto->value = atof(x->get_text());
1043                                 update_preview();
1044                         }
1045                 }
1046                 else
1047                 if(event_caller == y)
1048                 {
1049                         y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1050                                 track->automation->autos[AUTOMATION_PROJECTOR_Y],
1051                                 1);
1052                         if(y_auto)
1053                         {
1054                                 y_auto->value = atof(y->get_text());
1055                                 update_preview();
1056                         }
1057                 }
1058                 else
1059                 if(event_caller == z)
1060                 {
1061                         z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1062                                 track->automation->autos[AUTOMATION_PROJECTOR_Z],
1063                                 1);
1064                         if(z_auto)
1065                         {
1066                                 float zoom = atof(z->get_text());
1067                                 if(zoom > 10000) zoom = 10000; 
1068                                 else 
1069                                 if(zoom < 0) zoom = 0;
1070 //                      if (zoom != atof(z->get_text())) 
1071 //                              z->update(zoom);
1072                                 z_auto->value = zoom;
1074                                 mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
1075                                 mwindow->gui->canvas->draw_overlays();
1076                                 mwindow->gui->canvas->flash();
1077                                 mwindow->gui->unlock_window();
1079                                 update_preview();
1080                         }
1081                 }
1082         }
1085 void CWindowProjectorGUI::update()
1087         FloatAuto *x_auto = 0;
1088         FloatAuto *y_auto = 0;
1089         FloatAuto *z_auto = 0;
1090         Track *track = mwindow->cwindow->calculate_affected_track();
1092         if(track)
1093         {
1094                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1095                         &y_auto,
1096                         &z_auto,
1097                         track,
1098                         0,
1099                         0,
1100                         0,
1101                         0);
1102         }
1104         if(x_auto)
1105                 x->update(x_auto->value);
1106         if(y_auto)
1107                 y->update(y_auto->value);
1108         if(z_auto)
1109                 z->update(z_auto->value);
1112 // BezierAuto* CWindowProjectorGUI::get_keyframe()
1113 // {
1114 //      BezierAuto *keyframe = 0;
1115 //      Track *track = mwindow->cwindow->calculate_affected_track();
1116 //      if(track)
1117 //              keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
1118 //                      track->automation->autos[AUTOMATION_PROJECTOR]);
1119 //      return keyframe;
1120 // }
1159 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1160  : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
1162         this->gui = gui;
1163         this->mwindow = mwindow;
1164         set_tooltip(_("Left justify"));
1166 int CWindowProjectorLeft::handle_event()
1168         FloatAuto *x_auto = 0;
1169         FloatAuto *z_auto = 0;
1170         Track *track = mwindow->cwindow->calculate_affected_track();
1171         if(track)
1172         {
1173                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1174                         0,
1175                         &z_auto,
1176                         track,
1177                         0,
1178                         1,
1179                         0,
1180                         0);
1181         }
1182         if(x_auto && z_auto)
1183         {
1184                 x_auto->value = (double)track->track_w * z_auto->value / 2 - 
1185                         (double)mwindow->edl->session->output_w / 2;
1186                 gui->update();
1187                 gui->update_preview();
1188         }
1190         return 1;
1194 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1195  : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
1197         this->gui = gui;
1198         this->mwindow = mwindow;
1199         set_tooltip(_("Center horizontal"));
1201 int CWindowProjectorCenter::handle_event()
1203         FloatAuto *x_auto = 0;
1204         Track *track = mwindow->cwindow->calculate_affected_track();
1205         if(track)
1206                 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1207                         track->automation->autos[AUTOMATION_PROJECTOR_X],
1208                         1);
1210         if(x_auto)
1211         {
1212                 x_auto->value = 0;
1213                 gui->update();
1214                 gui->update_preview();
1215         }
1217         return 1;
1221 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1222  : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
1224         this->gui = gui;
1225         this->mwindow = mwindow;
1226         set_tooltip(_("Right justify"));
1228 int CWindowProjectorRight::handle_event()
1230         FloatAuto *x_auto = 0;
1231         FloatAuto *z_auto = 0;
1232         Track *track = mwindow->cwindow->calculate_affected_track();
1233         if(track)
1234         {
1235                 mwindow->cwindow->calculate_affected_autos(&x_auto,
1236                         0,
1237                         &z_auto,
1238                         track,
1239                         0,
1240                         1,
1241                         0,
1242                         0);
1243         }
1245         if(x_auto && z_auto)
1246         {
1247                 x_auto->value = -((double)track->track_w * z_auto->value / 2 - 
1248                         (double)mwindow->edl->session->output_w / 2);
1249                 gui->update();
1250                 gui->update_preview();
1251         }
1253         return 1;
1257 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1258  : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1260         this->gui = gui;
1261         this->mwindow = mwindow;
1262         set_tooltip(_("Top justify"));
1264 int CWindowProjectorTop::handle_event()
1266         FloatAuto *y_auto = 0;
1267         FloatAuto *z_auto = 0;
1268         Track *track = mwindow->cwindow->calculate_affected_track();
1269         if(track)
1270         {
1271                 mwindow->cwindow->calculate_affected_autos(0,
1272                         &y_auto,
1273                         &z_auto,
1274                         track,
1275                         0,
1276                         0,
1277                         1,
1278                         0);
1279         }
1281         if(y_auto && z_auto)
1282         {
1283                 y_auto->value = (double)track->track_h * z_auto->value / 2 - 
1284                         (double)mwindow->edl->session->output_h / 2;
1285                 gui->update();
1286                 gui->update_preview();
1287         }
1289         return 1;
1293 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1294  : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1296         this->gui = gui;
1297         this->mwindow = mwindow;
1298         set_tooltip(_("Center vertical"));
1300 int CWindowProjectorMiddle::handle_event()
1302         FloatAuto *y_auto = 0;
1303         Track *track = mwindow->cwindow->calculate_affected_track();
1304         if(track)
1305                 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1306                         track->automation->autos[AUTOMATION_PROJECTOR_Y], 1);
1308         if(y_auto)
1309         {
1310                 y_auto->value = 0;
1311                 gui->update();
1312                 gui->update_preview();
1313         }
1315         return 1;
1319 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1320  : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1322         this->gui = gui;
1323         this->mwindow = mwindow;
1324         set_tooltip(_("Bottom justify"));
1326 int CWindowProjectorBottom::handle_event()
1328         FloatAuto *y_auto = 0;
1329         FloatAuto *z_auto = 0;
1330         Track *track = mwindow->cwindow->calculate_affected_track();
1331         if(track)
1332         {
1333                 mwindow->cwindow->calculate_affected_autos(0,
1334                         &y_auto,
1335                         &z_auto,
1336                         track,
1337                         0,
1338                         0,
1339                         1,
1340                         0);
1341         }
1343         if(y_auto && z_auto)
1344         {
1345                 y_auto->value = -((double)track->track_h * z_auto->value / 2 - 
1346                         (double)mwindow->edl->session->output_h / 2);
1347                 gui->update();
1348                 gui->update_preview();
1349         }
1351         return 1;
1361 CWindowMaskMode::CWindowMaskMode(MWindow *mwindow, 
1362         CWindowToolGUI *gui, 
1363         int x, 
1364         int y,
1365         char *text)
1366  : BC_PopupMenu(x,
1367         y,
1368         200,
1369         text,
1370         1)
1372         this->mwindow = mwindow;
1373         this->gui = gui;
1376 void CWindowMaskMode::create_objects()
1378         add_item(new BC_MenuItem(mode_to_text(MASK_MULTIPLY_ALPHA)));
1379         add_item(new BC_MenuItem(mode_to_text(MASK_SUBTRACT_ALPHA)));
1382 char* CWindowMaskMode::mode_to_text(int mode)
1384         switch(mode)
1385         {
1386                 case MASK_MULTIPLY_ALPHA:
1387                         return _("Multiply alpha");
1388                         break;
1389                 
1390                 case MASK_SUBTRACT_ALPHA:
1391                         return _("Subtract alpha");
1392                         break;
1393         }
1395         return _("Subtract alpha");
1398 int CWindowMaskMode::text_to_mode(char *text)
1400         if(!strcasecmp(text, _("Multiply alpha")))
1401                 return MASK_MULTIPLY_ALPHA;
1402         else
1403         if(!strcasecmp(text, _("Subtract alpha")))
1404                 return MASK_SUBTRACT_ALPHA;
1406         return MASK_SUBTRACT_ALPHA;
1409 int CWindowMaskMode::handle_event()
1411         MaskAuto *keyframe;
1412         Track *track;
1413         MaskPoint *point;
1414         SubMask *mask;
1415         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1416                 keyframe, 
1417                 mask,
1418                 point,
1419                 0);
1421         if(track)
1422         {
1423                 ((MaskAuto*)track->automation->autos[AUTOMATION_MASK]->default_auto)->mode = 
1424                         text_to_mode(get_text());
1425         }
1427 //printf("CWindowMaskMode::handle_event 1\n");
1428         gui->update_preview();
1429         return 1;
1439 CWindowMaskDelete::CWindowMaskDelete(MWindow *mwindow, 
1440         CWindowToolGUI *gui, 
1441         int x, 
1442         int y)
1443  : BC_GenericButton(x, y, _("Delete"))
1445         this->mwindow = mwindow;
1446         this->gui = gui;
1449 int CWindowMaskDelete::handle_event()
1451         MaskAuto *keyframe;
1452         Track *track = mwindow->cwindow->calculate_affected_track();
1453         MaskPoint *point;
1454         SubMask *mask;
1457         if(track)
1458         {
1459                 MaskAutos *mask_autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
1460                 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
1461                         current; )
1462                 {
1463                         SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1466                         
1467                         for(int i = mwindow->cwindow->gui->affected_point;
1468                                 i < submask->points.total - 1;
1469                                 i++)
1470                         {
1471                                 *submask->points.values[i] = *submask->points.values[i + 1];
1472                         }
1474                         if(submask->points.total)
1475                         {
1476                                 submask->points.remove_object(
1477                                         submask->points.values[submask->points.total - 1]);
1478                         }
1481                         if(current == (MaskAuto*)mask_autos->default_auto)
1482                                 current = (MaskAuto*)mask_autos->first;
1483                         else
1484                                 current = (MaskAuto*)NEXT;
1485                 }
1486                 gui->update();
1487                 gui->update_preview();
1488         }
1491 //      ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1492 //              keyframe, 
1493 //              mask, 
1494 //              point,
1495 //              0);
1497 // Need to apply to every keyframe
1498         
1499 //      if(keyframe)
1500 //      {
1501 //              for(int i = mwindow->cwindow->gui->affected_point;
1502 //                      i < mask->points.total - 1;
1503 //                      i++)
1504 //              {
1505 //                      *mask->points.values[i] = *mask->points.values[i + 1];
1506 //              }
1507 //              
1508 //              if(mask->points.total)
1509 //              {
1510 //                      mask->points.remove_object(mask->points.values[mask->points.total - 1]);
1511 //              }
1512 // 
1513 //              gui->update();
1514 //              gui->update_preview();
1515 //      }
1517         return 1;
1520 int CWindowMaskDelete::keypress_event()
1522         if(get_keypress() == BACKSPACE ||
1523                 get_keypress() == DELETE) 
1524                 return handle_event();
1525         return 0;
1529 CWindowMaskCycleNext::CWindowMaskCycleNext(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1530  : BC_GenericButton(x, y, _("Cycle next"))
1532         this->mwindow = mwindow;
1533         this->gui = gui;
1535 int CWindowMaskCycleNext::handle_event()
1537         MaskAuto *keyframe;
1538         Track *track;
1539         MaskPoint *point;
1540         SubMask *mask;
1541         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1542                 keyframe,
1543                 mask,  
1544                 point,
1545                 0);
1547         MaskPoint *temp;
1549 // Should apply to all keyframes
1550         if(keyframe && mask->points.total)
1551         {
1552                 temp = mask->points.values[0];
1554                 for(int i = 0; i < mask->points.total - 1; i++)
1555                 {
1556                         mask->points.values[i] = mask->points.values[i + 1];
1557                 }
1558                 mask->points.values[mask->points.total - 1] = temp;
1560                 mwindow->cwindow->gui->affected_point--;
1561                 if(mwindow->cwindow->gui->affected_point < 0)
1562                         mwindow->cwindow->gui->affected_point = mask->points.total - 1;
1564                 gui->update();
1565                 gui->update_preview();
1566         }
1567         
1568         return 1;
1571 CWindowMaskCyclePrev::CWindowMaskCyclePrev(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1572  : BC_GenericButton(x, y, _("Cycle prev"))
1574         this->mwindow = mwindow;
1575         this->gui = gui;
1577 int CWindowMaskCyclePrev::handle_event()
1579         MaskAuto *keyframe;
1580         Track *track;
1581         MaskPoint *point;
1582         SubMask *mask;
1583         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1584                 keyframe,
1585                 mask, 
1586                 point,
1587                 0);
1589 // Should apply to all keyframes
1590         MaskPoint *temp;
1591         if(keyframe && mask->points.total)
1592         {
1593                 temp = mask->points.values[mask->points.total - 1];
1595                 for(int i = mask->points.total - 1; i > 0; i--)
1596                 {
1597                         mask->points.values[i] = mask->points.values[i - 1];
1598                 }
1599                 mask->points.values[0] = temp;
1601                 mwindow->cwindow->gui->affected_point++;
1602                 if(mwindow->cwindow->gui->affected_point >= mask->points.total)
1603                         mwindow->cwindow->gui->affected_point = 0;
1605                 gui->update();
1606                 gui->update_preview();
1607         }
1608         return 1;
1612 CWindowMaskNumber::CWindowMaskNumber(MWindow *mwindow, 
1613         CWindowToolGUI *gui, 
1614         int x, 
1615         int y)
1616  : BC_TumbleTextBox(gui, 
1617                 (int64_t)mwindow->edl->session->cwindow_mask,
1618                 (int64_t)0,
1619                 (int64_t)SUBMASKS - 1,
1620                 x, 
1621                 y, 
1622                 100)
1624         this->mwindow = mwindow;
1625         this->gui = gui;
1628 CWindowMaskNumber::~CWindowMaskNumber()
1632 int CWindowMaskNumber::handle_event()
1634         mwindow->edl->session->cwindow_mask = atol(get_text());
1635         gui->update();
1636         gui->update_preview();
1637         return 1;
1644 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1645  : BC_TumbleTextBox(gui, 
1646                 (int64_t)0,
1647                 (int64_t)0,
1648                 (int64_t)0xff,
1649                 x, 
1650                 y, 
1651                 100)
1653         this->mwindow = mwindow;
1654         this->gui = gui;
1656 CWindowMaskFeather::~CWindowMaskFeather()
1659 int CWindowMaskFeather::handle_event()
1661         MaskAuto *keyframe;
1662         Track *track;
1663         MaskPoint *point;
1664         SubMask *mask;
1665         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1666                 keyframe,
1667                 mask, 
1668                 point,
1669                 1);
1671         keyframe->feather = atof(get_text());
1672         gui->update_preview();
1673         return 1;
1676 CWindowMaskValue::CWindowMaskValue(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1677  : BC_ISlider(x, 
1678                         y,
1679                         0,
1680                         200, 
1681                         200, 
1682                         0, 
1683                         100, 
1684                         0)
1686         this->mwindow = mwindow;
1687         this->gui = gui;
1690 CWindowMaskValue::~CWindowMaskValue()
1694 int CWindowMaskValue::handle_event()
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                 1);
1706         keyframe->value = get_value();
1707         gui->update_preview();
1708         return 1;
1713 CWindowMaskBeforePlugins::CWindowMaskBeforePlugins(CWindowToolGUI *gui, int x, int y)
1714  : BC_CheckBox(x, 
1715         y, 
1716         1, 
1717         _("Apply mask before plugins"))
1719         this->gui = gui;
1722 int CWindowMaskBeforePlugins::handle_event()
1724         MaskAuto *keyframe;
1725         Track *track;
1726         MaskPoint *point;
1727         SubMask *mask;
1728         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1729                 keyframe,
1730                 mask, 
1731                 point,
1732                 1);
1734         keyframe->apply_before_plugins = get_value();
1735         gui->update_preview();
1736         return 1;
1746 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
1747  : CWindowToolGUI(mwindow, 
1748         thread,
1749         PROGRAM_NAME ": Mask",
1750         330,
1751         280)
1753         this->mwindow = mwindow;
1754         this->thread = thread;
1756 CWindowMaskGUI::~CWindowMaskGUI()
1758         delete number;
1759         delete feather;
1762 void CWindowMaskGUI::create_objects()
1764         int x = 10, y = 10;
1765         MaskAuto *keyframe = 0;
1766         Track *track = mwindow->cwindow->calculate_affected_track();
1767         if(track)
1768                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], 0);
1770         BC_Title *title;
1771         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
1772         add_subwindow(mode = new CWindowMaskMode(mwindow, 
1773                 this, 
1774                 x + title->get_w(), 
1775                 y,
1776                 ""));
1777         mode->create_objects();
1778         y += 40;
1779         add_subwindow(new BC_Title(x, y, _("Value:")));
1780         add_subwindow(value = new CWindowMaskValue(mwindow, this, x + 50, y));
1781         y += 30;
1782         add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
1783         y += 30;
1784         add_subwindow(new BC_Title(x, y, _("Mask number:")));
1785         number = new CWindowMaskNumber(mwindow, 
1786                 this, 
1787                 x + 110, 
1788                 y);
1789         number->create_objects();
1790         y += 30;
1791         add_subwindow(new BC_Title(x, y, _("Feather:")));
1792         feather = new CWindowMaskFeather(mwindow,
1793                 this,
1794                 x + 110,
1795                 y);
1796         feather->create_objects();
1797         y += 30;
1798         add_subwindow(title = new BC_Title(x, y, _("X:")));
1799         x += title->get_w();
1800         this->x = new CWindowCoord(this, 
1801                 x, 
1802                 y, 
1803                 (float)0.0);
1804         this->x->create_objects();
1805         x += 150;
1806         add_subwindow(title = new BC_Title(x, y, _("Y:")));
1807         x += title->get_w();
1808         this->y = new CWindowCoord(this, 
1809                 x, 
1810                 y, 
1811                 (float)0.0);
1812         this->y->create_objects();
1814         y += 30;
1815 //      add_subwindow(title = new BC_Title(x, y, _("Apply mask before plugins:")));
1816         
1817         add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this, 
1818                 10, 
1819                 y));
1820 //      this->apply_before_plugins->create_objects();
1823         update();
1826 void CWindowMaskGUI::get_keyframe(Track* &track, 
1827         MaskAuto* &keyframe, 
1828         SubMask* &mask, 
1829         MaskPoint* &point,
1830         int create_it)
1832         keyframe = 0;
1833         track = mwindow->cwindow->calculate_affected_track();
1834         if(track)
1835                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], create_it);
1836         else
1837                 keyframe = 0;
1839         if(keyframe)
1840                 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
1841         else
1842                 mask = 0;
1844         point = 0;
1845         if(keyframe)
1846         {
1847                 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
1848                         mwindow->cwindow->gui->affected_point >= 0)
1849                 {
1850                         point =  mask->points.values[mwindow->cwindow->gui->affected_point];
1851                 }
1852         }
1855 void CWindowMaskGUI::update()
1857         MaskAuto *keyframe;
1858         Track *track;
1859         MaskPoint *point;
1860         SubMask *mask;
1861 //printf("CWindowMaskGUI::update 1\n");
1862         get_keyframe(track, 
1863                 keyframe, 
1864                 mask,
1865                 point,
1866                 0);
1868 //printf("CWindowMaskGUI::update 1\n");
1869         if(point)
1870         {
1871                 x->update(point->x);
1872                 y->update(point->y);
1873         }
1874 //printf("CWindowMaskGUI::update 1\n");
1876         if(mask)
1877         {
1878                 feather->update((int64_t)keyframe->feather);
1879                 value->update((int64_t)keyframe->value);
1880                 apply_before_plugins->update((int64_t)keyframe->apply_before_plugins);
1881         }
1882 //printf("CWindowMaskGUI::update 1\n");
1884         number->update((int64_t)mwindow->edl->session->cwindow_mask);
1886 //printf("CWindowMaskGUI::update 1\n");
1887         if(track)
1888         {
1889                 mode->set_text(
1890                         CWindowMaskMode::mode_to_text(((MaskAuto*)track->automation->autos[AUTOMATION_MASK]->default_auto)->mode));
1891         }
1892 //printf("CWindowMaskGUI::update 2\n");
1895 void CWindowMaskGUI::handle_event()
1897         MaskAuto *keyframe;
1898         Track *track;
1899         MaskPoint *point;
1900         SubMask *mask;
1901         get_keyframe(track, 
1902                 keyframe, 
1903                 mask,
1904                 point,
1905                 0);
1907         if(point)
1908         {
1909                 point->x = atof(x->get_text());
1910                 point->y = atof(y->get_text());
1911         }
1913         update_preview();
1916 void CWindowMaskGUI::update_preview()
1918         mwindow->restart_brender();
1919         mwindow->sync_parameters(CHANGE_PARAMS);
1920         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1921                         CHANGE_NONE,
1922                         mwindow->edl,
1923                         1);
1924         mwindow->cwindow->gui->lock_window("CWindowMaskGUI::update_preview");
1925         mwindow->cwindow->gui->canvas->draw_refresh();
1926         mwindow->cwindow->gui->unlock_window();