r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / cwindowtool.C
blob8118ee820e0cdbdd5a98ef65abc466afafddd07d
1 #include "automation.h"
2 #include "bezierauto.h"
3 #include "bezierautos.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 "localsession.h"
15 #include "mainsession.h"
16 #include "maskauto.h"
17 #include "maskautos.h"
18 #include "mwindow.h"
19 #include "mwindowgui.h"
20 #include "theme.h"
21 #include "track.h"
22 #include "trackcanvas.h"
23 #include "transportque.h"
25 #include <libintl.h>
26 #define _(String) gettext(String)
27 #define gettext_noop(String) String
28 #define N_(String) gettext_noop (String)
30 CWindowTool::CWindowTool(MWindow *mwindow, CWindowGUI *gui)
31  : Thread()
33         this->mwindow = mwindow;
34         this->gui = gui;
35         tool_gui = 0;
36         done = 0;
37         current_tool = CWINDOW_NONE;
38         set_synchronous(1);
39         input_lock = new Mutex;
40         input_lock->lock();
41         output_lock = new Mutex;
44 CWindowTool::~CWindowTool()
46         done = 1;
47         stop_tool();
48         input_lock->unlock();
49         Thread::join();
50         delete input_lock;
51         delete output_lock;
54 void CWindowTool::start_tool(int operation)
56         CWindowToolGUI *new_gui = 0;
57         int result = 0;
59 //printf("CWindowTool::start_tool 1\n");
60         if(current_tool != operation)
61         {
62                 current_tool = operation;
63                 switch(operation)
64                 {
65                         case CWINDOW_CROP:
66                                 new_gui = new CWindowCropGUI(mwindow, this);
67                                 break;
68                         case CWINDOW_CAMERA:
69                                 new_gui = new CWindowCameraGUI(mwindow, this);
70                                 break;
71                         case CWINDOW_PROJECTOR:
72                                 new_gui = new CWindowProjectorGUI(mwindow, this);
73                                 break;
74                         case CWINDOW_MASK:
75                                 new_gui = new CWindowMaskGUI(mwindow, this);
76                                 break;
77                         default:
78                                 result = 1;
79                                 stop_tool();
80                                 break;
81                 }
83 //printf("CWindowTool::start_tool 1\n");
86                 if(!result)
87                 {
88                         stop_tool();
89                         output_lock->lock();
90                         this->tool_gui = new_gui;
91                         tool_gui->create_objects();
92                         input_lock->unlock();
93                 }
94 //printf("CWindowTool::start_tool 1\n");
95         }
96         else
97         if(tool_gui) 
98         {
99                 tool_gui->lock_window();
100                 tool_gui->update();
101                 tool_gui->unlock_window();
102         }
104 //printf("CWindowTool::start_tool 2\n");
109 void CWindowTool::stop_tool()
111         if(tool_gui)
112         {
113                 tool_gui->lock_window();
114                 tool_gui->set_done(0);
115                 tool_gui->unlock_window();
116         }
119 void CWindowTool::run()
121         while(!done)
122         {
123                 input_lock->lock();
124                 if(!done)
125                 {
126                         tool_gui->run_window();
127                         delete tool_gui;
128                         tool_gui = 0;
129                 }
130                 output_lock->unlock();
131         }
134 void CWindowTool::update_show_window()
136         if(tool_gui)
137         {
138                 tool_gui->lock_window();
140                 if(mwindow->edl->session->tool_window) 
141                 {
142                         tool_gui->update();
143                         tool_gui->show_window();
144                 }
145                 else
146                         tool_gui->hide_window();
147                 tool_gui->flush();
149                 tool_gui->unlock_window();
150         }
153 void CWindowTool::update_values()
155         if(tool_gui)
156         {
157 //printf("CWindowTool::update_values 1\n");
158                 tool_gui->lock_window();
159                 tool_gui->update();
160                 tool_gui->flush();
161                 tool_gui->unlock_window();
162 //printf("CWindowTool::update_values 2\n");
163         }
172 CWindowToolGUI::CWindowToolGUI(MWindow *mwindow, 
173         CWindowTool *thread, 
174         char *title,
175         int w, 
176         int h)
177  : BC_Window(title,
178         mwindow->session->ctool_x,
179         mwindow->session->ctool_y,
180         w,
181         h,
182         w,
183         h,
184         0,
185         0,
186         1)
188         this->mwindow = mwindow;
189         this->thread = thread;
190         current_operation = 0;
193 CWindowToolGUI::~CWindowToolGUI()
197 int CWindowToolGUI::close_event()
199         hide_window();
200         flush();
201         mwindow->edl->session->tool_window = 0;
202         thread->gui->lock_window();
203         thread->gui->composite_panel->set_operation(mwindow->edl->session->cwindow_operation);
204         thread->gui->flush();
205         thread->gui->unlock_window();
206         return 1;
209 int CWindowToolGUI::keypress_event()
211         if(get_keypress() == 'w' || get_keypress() == 'W')
212                 return close_event();
213         return 0;
216 int CWindowToolGUI::translation_event()
218         mwindow->session->ctool_x = get_x();
219         mwindow->session->ctool_y = get_y();
220         return 0;
228 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value)
229  : BC_TumbleTextBox(gui, 
230                 (float)value,
231                 (float)-65536,
232                 (float)65536,
233                 x, 
234                 y, 
235                 100)
237         this->gui = gui;
240 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
241  : BC_TumbleTextBox(gui, 
242                 (int64_t)value,
243                 (int64_t)-65536,
244                 (int64_t)65536,
245                 x, 
246                 y, 
247                 100)
249         this->gui = gui;
251 int CWindowCoord::handle_event()
253         gui->event_caller = this;
254         gui->handle_event();
255         return 1;
259 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
260  : BC_GenericButton(x, y, _("Do it"))
262         this->mwindow = mwindow;
263         this->gui = gui;
265 int CWindowCropOK::handle_event()
267         mwindow->crop_video();
268         return 1;
272 int CWindowCropOK::keypress_event()
274         if(get_keypress() == 0xd) 
275         {
276                 handle_event();
277                 return 1;
278         }
279         return 0;
288 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
289  : CWindowToolGUI(mwindow, 
290         thread,
291         PROGRAM_NAME ": Crop",
292         330,
293         100)
298 CWindowCropGUI::~CWindowCropGUI()
302 void CWindowCropGUI::create_objects()
304         int x = 10, y = 10;
305         BC_TumbleTextBox *textbox;
306         BC_Title *title;
308         add_subwindow(title = new BC_Title(x, y, _("X1:")));
309         x += title->get_w();
310         x1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_x1);
311         x1->create_objects();
312         x += x1->get_w() + 10;
314         add_subwindow(title = new BC_Title(x, y, _("Y1:")));
315         x += title->get_w();
316         y1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_y1);
317         y1->create_objects();
318         y += y1->get_h() + 5;
319         x = 10;
321         add_subwindow(title = new BC_Title(x, y, _("X2:")));
322         x += title->get_w();
323         x2 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_x2);
324         x2->create_objects();
325         x += x2->get_w() + 10;
327         add_subwindow(title = new BC_Title(x, y, _("Y2:")));
328         x += title->get_w();
329         y2 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_y2);
330         y2->create_objects();
331         y += y2->get_h() + 5;
332         x = 10;
333         add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
335         if(mwindow->edl->session->tool_window) show_window();
336         flush();
339 void CWindowCropGUI::handle_event()
341         mwindow->edl->session->crop_x1 = atol(x1->get_text());
342         mwindow->edl->session->crop_y1 = atol(y1->get_text());
343         mwindow->edl->session->crop_x2 = atol(x2->get_text());
344         mwindow->edl->session->crop_y2 = atol(y2->get_text());
345         mwindow->cwindow->gui->lock_window();
346         mwindow->cwindow->gui->canvas->draw_refresh();
347         mwindow->cwindow->gui->unlock_window();
350 void CWindowCropGUI::update()
352         x1->update((int64_t)mwindow->edl->session->crop_x1);
353         y1->update((int64_t)mwindow->edl->session->crop_y1);
354         x2->update((int64_t)mwindow->edl->session->crop_x2);
355         y2->update((int64_t)mwindow->edl->session->crop_y2);
369 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
370  : CWindowToolGUI(mwindow, 
371         thread,
372         PROGRAM_NAME ": Camera",
373         170,
374         170)
377 CWindowCameraGUI::~CWindowCameraGUI()
381 void CWindowCameraGUI::create_objects()
383         int x = 10, y = 10, x1;
384         Track *track = mwindow->cwindow->calculate_affected_track();
385         BezierAuto *keyframe = 0;
386         FloatAuto *zoom_keyframe = 0;
387         BC_Title *title;
388         BC_Button *button;
390         if(track)
391         {
392                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
393                         track->automation->camera_autos, 
394                         0);
395                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
396                         track->automation->czoom_autos, 
397                         0);
398         }
400         add_subwindow(title = new BC_Title(x, y, _("X:")));
401         x += title->get_w();
402         this->x = new CWindowCoord(this, 
403                 x, 
404                 y, 
405                 keyframe ? keyframe->center_x : (float)0);
406         this->x->create_objects();
407         y += 30;
408         x = 10;
409         add_subwindow(title = new BC_Title(x, y, _("Y:")));
410         x += title->get_w();
411         this->y = new CWindowCoord(this, 
412                 x, 
413                 y, 
414                 keyframe ? keyframe->center_y : (float)0);
415         this->y->create_objects();
416         y += 30;
417         x = 10;
418         add_subwindow(title = new BC_Title(x, y, _("Z:")));
419         x += title->get_w();
420         this->z = new CWindowCoord(this, 
421                 x, 
422                 y, 
423                 zoom_keyframe ? zoom_keyframe->value : (float)1);
424         this->z->create_objects();
426         y += 30;
427         x1 = 10;
428         add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
429         x1 += button->get_w();
430         add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
431         x1 += button->get_w();
432         add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
434         y += button->get_h();
435         x1 = 10;
436         add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
437         x1 += button->get_w();
438         add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
439         x1 += button->get_w();
440         add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
444         if(mwindow->edl->session->tool_window) show_window();
445         flush();
448 void CWindowCameraGUI::update_preview()
450 //printf("CWindowCameraGUI::update_preview 1\n");
451         mwindow->restart_brender();
452         mwindow->sync_parameters(CHANGE_PARAMS);
454 //printf("CWindowCameraGUI::update_preview 1\n");
455         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
456                         CHANGE_NONE,
457                         mwindow->edl,
458                         1);
459 //printf("CWindowCameraGUI::update_preview 1\n");
460         mwindow->cwindow->gui->lock_window();
461 //printf("CWindowCameraGUI::update_preview 1\n");
462         mwindow->cwindow->gui->canvas->draw_refresh();
463 //printf("CWindowCameraGUI::update_preview 2\n");
464         mwindow->cwindow->gui->unlock_window();
465 //printf("CWindowCameraGUI::update_preview 3\n");
469 void CWindowCameraGUI::handle_event()
471         BezierAuto *keyframe = 0;
472         FloatAuto *zoom_keyframe = 0;
473         Track *track = mwindow->cwindow->calculate_affected_track();
474         if(track)
475         {
476                 if(event_caller == z)
477                         zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
478                                 track->automation->czoom_autos,
479                                 1);
480                 else
481                         keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
482                                 track->automation->camera_autos,
483                                 1);
484         }
486         if(keyframe)
487         {
488                 keyframe->center_x = atof(x->get_text());
489                 keyframe->center_y = atof(y->get_text());
490                 update_preview();
491         }
492         else
493         if(zoom_keyframe)
494         {
495                 zoom_keyframe->value = atof(z->get_text());
496                 mwindow->gui->lock_window();
497                 mwindow->gui->canvas->draw_overlays();
498                 mwindow->gui->canvas->flash();
499                 mwindow->gui->unlock_window();
500                 update_preview();
501         }
504 void CWindowCameraGUI::update()
506         BezierAuto *keyframe = 0;
507         FloatAuto *zoom_keyframe = 0;
508         Track *track = mwindow->cwindow->calculate_affected_track();
510         if(track)
511         {
512                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
513                         track->automation->camera_autos, 
514                         0);
515                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
516                         track->automation->czoom_autos, 
517                         0);
518         }
520         if(keyframe)
521         {
522                 x->update(keyframe->center_x);
523                 y->update(keyframe->center_y);
524         }
526         if(zoom_keyframe)
527         {
528                 z->update(zoom_keyframe->value);
529         }
532 BezierAuto* CWindowCameraGUI::get_keyframe()
534         BezierAuto *keyframe = 0;
535         Track *track = mwindow->cwindow->calculate_affected_track();
536         if(track)
537                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
538         return keyframe;
543 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
544  : BC_Button(x, y, mwindow->theme->left_justify)
546         this->gui = gui;
547         this->mwindow = mwindow;
548         set_tooltip(_("Left justify"));
550 int CWindowCameraLeft::handle_event()
552         BezierAuto *keyframe = 0;
553         Track *track = mwindow->cwindow->calculate_affected_track();
554         if(track)
555                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
557         if(keyframe)
558         {
559                 int w = 0, h = 0;
560                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
561                         w,
562                         h);
564                 if(w && h)
565                 {
566                         keyframe->center_x = 
567                                 (double)track->track_w / keyframe->center_z / 2 - 
568                                 (double)w / 2;
569                         gui->update();
570                         gui->update_preview();
571                 }
572         }
574         return 1;
578 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
579  : BC_Button(x, y, mwindow->theme->center_justify)
581         this->gui = gui;
582         this->mwindow = mwindow;
583         set_tooltip(_("Center horizontal"));
585 int CWindowCameraCenter::handle_event()
587         BezierAuto *keyframe = 0;
588         Track *track = mwindow->cwindow->calculate_affected_track();
589         if(track)
590                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
592         if(keyframe)
593         {
594                 keyframe->center_x = 0;
595                 gui->update();
596                 gui->update_preview();
597         }
599         return 1;
603 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
604  : BC_Button(x, y, mwindow->theme->right_justify)
606         this->gui = gui;
607         this->mwindow = mwindow;
608         set_tooltip(_("Right justify"));
610 int CWindowCameraRight::handle_event()
612         BezierAuto *keyframe = 0;
613         Track *track = mwindow->cwindow->calculate_affected_track();
614         if(track)
615                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
617         if(keyframe)
618         {
619                 int w = 0, h = 0;
620                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
621                         w,
622                         h);
624                 if(w && h)
625                 {
626                         keyframe->center_x = -((double)track->track_w / keyframe->center_z / 2 - 
627                                 (double)w / 2);
628                         gui->update();
629                         gui->update_preview();
630                 }
631         }
633         return 1;
637 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
638  : BC_Button(x, y, mwindow->theme->top_justify)
640         this->gui = gui;
641         this->mwindow = mwindow;
642         set_tooltip(_("Top justify"));
644 int CWindowCameraTop::handle_event()
646         BezierAuto *keyframe = 0;
647         Track *track = mwindow->cwindow->calculate_affected_track();
648         if(track)
649                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
651         if(keyframe)
652         {
653                 int w = 0, h = 0;
654                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
655                         w,
656                         h);
658                 if(w && h)
659                 {
660                         keyframe->center_y = (double)track->track_h / keyframe->center_z / 2 - 
661                                 (double)h / 2;
662                         gui->update();
663                         gui->update_preview();
664                 }
665         }
667         return 1;
671 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
672  : BC_Button(x, y, mwindow->theme->middle_justify)
674         this->gui = gui;
675         this->mwindow = mwindow;
676         set_tooltip(_("Center vertical"));
678 int CWindowCameraMiddle::handle_event()
680         BezierAuto *keyframe = 0;
681         Track *track = mwindow->cwindow->calculate_affected_track();
682         if(track)
683                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
685         if(keyframe)
686         {
687                 keyframe->center_y = 0;
688                 gui->update();
689                 gui->update_preview();
690         }
692         return 1;
696 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
697  : BC_Button(x, y, mwindow->theme->bottom_justify)
699         this->gui = gui;
700         this->mwindow = mwindow;
701         set_tooltip(_("Bottom justify"));
703 int CWindowCameraBottom::handle_event()
705         BezierAuto *keyframe = 0;
706         Track *track = mwindow->cwindow->calculate_affected_track();
707         if(track)
708                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
710         if(keyframe)
711         {
712                 int w = 0, h = 0;
713                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
714                         w,
715                         h);
717                 if(w && h)
718                 {
719                         keyframe->center_y = -((double)track->track_h / keyframe->center_z / 2 - 
720                                 (double)h / 2);
721                         gui->update();
722                         gui->update_preview();
723                 }
724         }
726         return 1;
745 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
746  : CWindowToolGUI(mwindow, 
747         thread,
748         PROGRAM_NAME ": Projector",
749         170,
750         170)
753 CWindowProjectorGUI::~CWindowProjectorGUI()
756 void CWindowProjectorGUI::create_objects()
758         int x = 10, y = 10, x1;
759         Track *track = mwindow->cwindow->calculate_affected_track();
760         BezierAuto *keyframe = 0;
761         FloatAuto *zoom_keyframe = 0;
762         BC_Title *title;
763         BC_Button *button;
765         if(track)
766         {
767                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
768                         track->automation->projector_autos, 
769                         0);
770                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
771                         track->automation->pzoom_autos, 
772                         0);
773         }
775         add_subwindow(title = new BC_Title(x, y, _("X:")));
776         x += title->get_w();
777         this->x = new CWindowCoord(this, 
778                 x, 
779                 y, 
780                 keyframe ? keyframe->center_x : (float)0);
781         this->x->create_objects();
782         y += 30;
783         x = 10;
784         add_subwindow(title = new BC_Title(x, y, _("Y:")));
785         x += title->get_w();
786         this->y = new CWindowCoord(this, 
787                 x, 
788                 y, 
789                 keyframe ? keyframe->center_y : (float)0);
790         this->y->create_objects();
791         y += 30;
792         x = 10;
793         add_subwindow(title = new BC_Title(x, y, _("Z:")));
794         x += title->get_w();
795         this->z = new CWindowCoord(this, 
796                 x, 
797                 y, 
798                 zoom_keyframe ? zoom_keyframe->value : (float)1);
799         this->z->create_objects();
801         y += 30;
802         x1 = 10;
803         add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
804         x1 += button->get_w();
805         add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
806         x1 += button->get_w();
807         add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
809         y += button->get_h();
810         x1 = 10;
811         add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
812         x1 += button->get_w();
813         add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
814         x1 += button->get_w();
815         add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
818         if(mwindow->edl->session->tool_window) show_window();
819         flush();
822 void CWindowProjectorGUI::update_preview()
824         mwindow->restart_brender();
825         mwindow->sync_parameters(CHANGE_PARAMS);
826         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
827                         CHANGE_NONE,
828                         mwindow->edl,
829                         1);
830         mwindow->cwindow->gui->lock_window();
831         mwindow->cwindow->gui->canvas->draw_refresh();
832         mwindow->cwindow->gui->unlock_window();
835 void CWindowProjectorGUI::handle_event()
837         BezierAuto *keyframe = 0;
838         FloatAuto *zoom_keyframe = 0;
839         Track *track = mwindow->cwindow->calculate_affected_track();
841         if(track)
842         {
843                 if(event_caller == z)
844                         zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
845                                 track->automation->pzoom_autos,
846                                 1);
847                 else
848                         keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
849                                 track->automation->projector_autos,
850                                 1);
851         }
853         if(keyframe)
854         {
855                 keyframe->center_x = atof(x->get_text());
856                 keyframe->center_y = atof(y->get_text());
857                 keyframe->center_z = atof(z->get_text());
858                 update_preview();
859         }
860         else
861         if(zoom_keyframe)
862         {
863                 zoom_keyframe->value = atof(z->get_text());
864                 mwindow->gui->lock_window();
865                 mwindow->gui->canvas->draw_overlays();
866                 mwindow->gui->canvas->flash();
867                 mwindow->gui->unlock_window();
868                 update_preview();
869         }
872 void CWindowProjectorGUI::update()
874         BezierAuto *keyframe = 0;
875         FloatAuto *zoom_keyframe = 0;
876         Track *track = mwindow->cwindow->calculate_affected_track();
878         if(track)
879         {
880                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
881                         track->automation->projector_autos, 
882                         0);
883                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
884                         track->automation->pzoom_autos, 
885                         0);
886         }
888         if(keyframe)
889         {
890                 x->update(keyframe->center_x);
891                 y->update(keyframe->center_y);
892         }
894         if(zoom_keyframe)
895         {
896                 z->update(zoom_keyframe->value);
897         }
900 BezierAuto* CWindowProjectorGUI::get_keyframe()
902         BezierAuto *keyframe = 0;
903         Track *track = mwindow->cwindow->calculate_affected_track();
904         if(track)
905                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
906         return keyframe;
946 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
947  : BC_Button(x, y, mwindow->theme->left_justify)
949         this->gui = gui;
950         this->mwindow = mwindow;
951         set_tooltip(_("Left justify"));
953 int CWindowProjectorLeft::handle_event()
955         BezierAuto *keyframe = 0;
956         Track *track = mwindow->cwindow->calculate_affected_track();
957         if(track)
958                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
960         if(keyframe)
961         {
962                 keyframe->center_x = (double)track->track_w * keyframe->center_z / 2 - 
963                         (double)mwindow->edl->session->output_w / 2;
964                 gui->update();
965                 gui->update_preview();
966         }
968         return 1;
972 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
973  : BC_Button(x, y, mwindow->theme->center_justify)
975         this->gui = gui;
976         this->mwindow = mwindow;
977         set_tooltip(_("Center horizontal"));
979 int CWindowProjectorCenter::handle_event()
981         BezierAuto *keyframe = 0;
982         Track *track = mwindow->cwindow->calculate_affected_track();
983         if(track)
984                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
986         if(keyframe)
987         {
988                 keyframe->center_x = 0;
989                 gui->update();
990                 gui->update_preview();
991         }
993         return 1;
997 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
998  : BC_Button(x, y, mwindow->theme->right_justify)
1000         this->gui = gui;
1001         this->mwindow = mwindow;
1002         set_tooltip(_("Right justify"));
1004 int CWindowProjectorRight::handle_event()
1006         BezierAuto *keyframe = 0;
1007         Track *track = mwindow->cwindow->calculate_affected_track();
1008         if(track)
1009                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
1011         if(keyframe)
1012         {
1013                 keyframe->center_x = -((double)track->track_w * keyframe->center_z / 2 - 
1014                         (double)mwindow->edl->session->output_w / 2);
1015                 gui->update();
1016                 gui->update_preview();
1017         }
1019         return 1;
1023 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1024  : BC_Button(x, y, mwindow->theme->top_justify)
1026         this->gui = gui;
1027         this->mwindow = mwindow;
1028         set_tooltip(_("Top justify"));
1030 int CWindowProjectorTop::handle_event()
1032         BezierAuto *keyframe = 0;
1033         Track *track = mwindow->cwindow->calculate_affected_track();
1034         if(track)
1035                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
1037         if(keyframe)
1038         {
1039                 keyframe->center_y = (double)track->track_h * keyframe->center_z / 2 - 
1040                         (double)mwindow->edl->session->output_h / 2;
1041                 gui->update();
1042                 gui->update_preview();
1043         }
1045         return 1;
1049 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1050  : BC_Button(x, y, mwindow->theme->middle_justify)
1052         this->gui = gui;
1053         this->mwindow = mwindow;
1054         set_tooltip(_("Center vertical"));
1056 int CWindowProjectorMiddle::handle_event()
1058         BezierAuto *keyframe = 0;
1059         Track *track = mwindow->cwindow->calculate_affected_track();
1060         if(track)
1061                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
1063         if(keyframe)
1064         {
1065                 keyframe->center_y = 0;
1066                 gui->update();
1067                 gui->update_preview();
1068         }
1070         return 1;
1074 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1075  : BC_Button(x, y, mwindow->theme->bottom_justify)
1077         this->gui = gui;
1078         this->mwindow = mwindow;
1079         set_tooltip(_("Bottom justify"));
1081 int CWindowProjectorBottom::handle_event()
1083         BezierAuto *keyframe = 0;
1084         Track *track = mwindow->cwindow->calculate_affected_track();
1085         if(track)
1086                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
1088         if(keyframe)
1089         {
1090                 keyframe->center_y = -((double)track->track_h * keyframe->center_z / 2 - 
1091                         (double)mwindow->edl->session->output_h / 2);
1092                 gui->update();
1093                 gui->update_preview();
1094         }
1096         return 1;
1106 CWindowMaskMode::CWindowMaskMode(MWindow *mwindow, 
1107         CWindowToolGUI *gui, 
1108         int x, 
1109         int y,
1110         char *text)
1111  : BC_PopupMenu(x,
1112         y,
1113         200,
1114         text,
1115         1)
1117         this->mwindow = mwindow;
1118         this->gui = gui;
1121 void CWindowMaskMode::create_objects()
1123         add_item(new BC_MenuItem(mode_to_text(MASK_MULTIPLY_ALPHA)));
1124         add_item(new BC_MenuItem(mode_to_text(MASK_SUBTRACT_ALPHA)));
1127 char* CWindowMaskMode::mode_to_text(int mode)
1129         switch(mode)
1130         {
1131                 case MASK_MULTIPLY_ALPHA:
1132                         return _("Multiply alpha");
1133                         break;
1134                 
1135                 case MASK_SUBTRACT_ALPHA:
1136                         return _("Subtract alpha");
1137                         break;
1138         }
1140         return _("Subtract alpha");
1143 int CWindowMaskMode::text_to_mode(char *text)
1145         if(!strcasecmp(text, _("Multiply alpha")))
1146                 return MASK_MULTIPLY_ALPHA;
1147         else
1148         if(!strcasecmp(text, _("Subtract alpha")))
1149                 return MASK_SUBTRACT_ALPHA;
1151         return MASK_SUBTRACT_ALPHA;
1154 int CWindowMaskMode::handle_event()
1156         MaskAuto *keyframe;
1157         Track *track;
1158         MaskPoint *point;
1159         SubMask *mask;
1160         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1161                 keyframe, 
1162                 mask,
1163                 point,
1164                 0);
1166         if(track)
1167         {
1168                 ((MaskAuto*)track->automation->mask_autos->default_auto)->mode = 
1169                         text_to_mode(get_text());
1170         }
1172 //printf("CWindowMaskMode::handle_event 1\n");
1173         gui->update_preview();
1174         return 1;
1184 CWindowMaskDelete::CWindowMaskDelete(MWindow *mwindow, 
1185         CWindowToolGUI *gui, 
1186         int x, 
1187         int y)
1188  : BC_GenericButton(x, y, _("Delete"))
1190         this->mwindow = mwindow;
1191         this->gui = gui;
1194 int CWindowMaskDelete::handle_event()
1196         MaskAuto *keyframe;
1197         Track *track = mwindow->cwindow->calculate_affected_track();
1198         MaskPoint *point;
1199         SubMask *mask;
1202         if(track)
1203         {
1204                 MaskAutos *mask_autos = track->automation->mask_autos;
1205                 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
1206                         current; )
1207                 {
1208                         SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1211                         
1212                         for(int i = mwindow->cwindow->gui->affected_point;
1213                                 i < submask->points.total - 1;
1214                                 i++)
1215                         {
1216                                 *submask->points.values[i] = *submask->points.values[i + 1];
1217                         }
1219                         if(submask->points.total)
1220                         {
1221                                 submask->points.remove_object(
1222                                         submask->points.values[submask->points.total - 1]);
1223                         }
1226                         if(current == (MaskAuto*)mask_autos->default_auto)
1227                                 current = (MaskAuto*)mask_autos->first;
1228                         else
1229                                 current = (MaskAuto*)NEXT;
1230                 }
1231                 gui->update();
1232                 gui->update_preview();
1233         }
1236 //      ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1237 //              keyframe, 
1238 //              mask, 
1239 //              point,
1240 //              0);
1242 // Need to apply to every keyframe
1243         
1244 //      if(keyframe)
1245 //      {
1246 //              for(int i = mwindow->cwindow->gui->affected_point;
1247 //                      i < mask->points.total - 1;
1248 //                      i++)
1249 //              {
1250 //                      *mask->points.values[i] = *mask->points.values[i + 1];
1251 //              }
1252 //              
1253 //              if(mask->points.total)
1254 //              {
1255 //                      mask->points.remove_object(mask->points.values[mask->points.total - 1]);
1256 //              }
1257 // 
1258 //              gui->update();
1259 //              gui->update_preview();
1260 //      }
1262         return 1;
1265 int CWindowMaskDelete::keypress_event()
1267         if(get_keypress() == BACKSPACE ||
1268                 get_keypress() == DELETE) 
1269                 return handle_event();
1270         return 0;
1274 CWindowMaskCycleNext::CWindowMaskCycleNext(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1275  : BC_GenericButton(x, y, _("Cycle next"))
1277         this->mwindow = mwindow;
1278         this->gui = gui;
1280 int CWindowMaskCycleNext::handle_event()
1282         MaskAuto *keyframe;
1283         Track *track;
1284         MaskPoint *point;
1285         SubMask *mask;
1286         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1287                 keyframe,
1288                 mask,  
1289                 point,
1290                 0);
1292         MaskPoint *temp;
1294 // Should apply to all keyframes
1295         if(keyframe && mask->points.total)
1296         {
1297                 temp = mask->points.values[0];
1299                 for(int i = 0; i < mask->points.total - 1; i++)
1300                 {
1301                         mask->points.values[i] = mask->points.values[i + 1];
1302                 }
1303                 mask->points.values[mask->points.total - 1] = temp;
1305                 mwindow->cwindow->gui->affected_point--;
1306                 if(mwindow->cwindow->gui->affected_point < 0)
1307                         mwindow->cwindow->gui->affected_point = mask->points.total - 1;
1309                 gui->update();
1310                 gui->update_preview();
1311         }
1312         
1313         return 1;
1316 CWindowMaskCyclePrev::CWindowMaskCyclePrev(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1317  : BC_GenericButton(x, y, _("Cycle prev"))
1319         this->mwindow = mwindow;
1320         this->gui = gui;
1322 int CWindowMaskCyclePrev::handle_event()
1324         MaskAuto *keyframe;
1325         Track *track;
1326         MaskPoint *point;
1327         SubMask *mask;
1328         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1329                 keyframe,
1330                 mask, 
1331                 point,
1332                 0);
1334 // Should apply to all keyframes
1335         MaskPoint *temp;
1336         if(keyframe && mask->points.total)
1337         {
1338                 temp = mask->points.values[mask->points.total - 1];
1340                 for(int i = mask->points.total - 1; i > 0; i--)
1341                 {
1342                         mask->points.values[i] = mask->points.values[i - 1];
1343                 }
1344                 mask->points.values[0] = temp;
1346                 mwindow->cwindow->gui->affected_point++;
1347                 if(mwindow->cwindow->gui->affected_point >= mask->points.total)
1348                         mwindow->cwindow->gui->affected_point = 0;
1350                 gui->update();
1351                 gui->update_preview();
1352         }
1353         return 1;
1357 CWindowMaskNumber::CWindowMaskNumber(MWindow *mwindow, 
1358         CWindowToolGUI *gui, 
1359         int x, 
1360         int y)
1361  : BC_TumbleTextBox(gui, 
1362                 (int64_t)mwindow->edl->session->cwindow_mask,
1363                 (int64_t)0,
1364                 (int64_t)SUBMASKS - 1,
1365                 x, 
1366                 y, 
1367                 100)
1369         this->mwindow = mwindow;
1370         this->gui = gui;
1373 CWindowMaskNumber::~CWindowMaskNumber()
1377 int CWindowMaskNumber::handle_event()
1379         mwindow->edl->session->cwindow_mask = atol(get_text());
1380         gui->update();
1381         gui->update_preview();
1382         return 1;
1389 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1390  : BC_TumbleTextBox(gui, 
1391                 (int64_t)0,
1392                 (int64_t)0,
1393                 (int64_t)0xff,
1394                 x, 
1395                 y, 
1396                 100)
1398         this->mwindow = mwindow;
1399         this->gui = gui;
1401 CWindowMaskFeather::~CWindowMaskFeather()
1404 int CWindowMaskFeather::handle_event()
1406         MaskAuto *keyframe;
1407         Track *track;
1408         MaskPoint *point;
1409         SubMask *mask;
1410         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1411                 keyframe,
1412                 mask, 
1413                 point,
1414                 1);
1416         keyframe->feather = atof(get_text());
1417         gui->update_preview();
1418         return 1;
1421 CWindowMaskValue::CWindowMaskValue(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1422  : BC_ISlider(x, 
1423                         y,
1424                         0,
1425                         200, 
1426                         200, 
1427                         0, 
1428                         100, 
1429                         0)
1431         this->mwindow = mwindow;
1432         this->gui = gui;
1435 CWindowMaskValue::~CWindowMaskValue()
1439 int CWindowMaskValue::handle_event()
1441         MaskAuto *keyframe;
1442         Track *track;
1443         MaskPoint *point;
1444         SubMask *mask;
1445         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1446                 keyframe,
1447                 mask, 
1448                 point,
1449                 1);
1451         keyframe->value = get_value();
1452         gui->update_preview();
1453         return 1;
1466 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
1467  : CWindowToolGUI(mwindow, 
1468         thread,
1469         PROGRAM_NAME ": Mask",
1470         330,
1471         280)
1473         this->mwindow = mwindow;
1474         this->thread = thread;
1476 CWindowMaskGUI::~CWindowMaskGUI()
1478         delete number;
1479         delete feather;
1482 void CWindowMaskGUI::create_objects()
1484 //printf("CWindowMaskGUI::create_objects 1\n");
1485         int x = 10, y = 10;
1486         MaskAuto *keyframe = 0;
1487         Track *track = mwindow->cwindow->calculate_affected_track();
1488         if(track)
1489                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->mask_autos, 0);
1490 //printf("CWindowMaskGUI::create_objects 1\n");
1492         BC_Title *title;
1493         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
1494         add_subwindow(mode = new CWindowMaskMode(mwindow, 
1495                 this, 
1496                 x + title->get_w(), 
1497                 y,
1498                 ""));
1499 //printf("CWindowMaskGUI::create_objects 1\n");
1500         mode->create_objects();
1501         y += 40;
1502         add_subwindow(new BC_Title(x, y, _("Value:")));
1503         add_subwindow(value = new CWindowMaskValue(mwindow, this, x + 50, y));
1504         y += 30;
1505         add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
1506         y += 30;
1507 //      add_subwindow(next_point = new CWindowMaskCycleNext(mwindow, this, x, y));
1508 //      y += 30;
1509 //      add_subwindow(prev_point = new CWindowMaskCyclePrev(mwindow, this, x, y));
1510 //      y += 40;
1511         add_subwindow(new BC_Title(x, y, _("Mask number:")));
1512         number = new CWindowMaskNumber(mwindow, 
1513                 this, 
1514                 x + 110, 
1515                 y);
1516 //printf("CWindowMaskGUI::create_objects 1\n");
1517         number->create_objects();
1518         y += 30;
1519         add_subwindow(new BC_Title(x, y, _("Feather:")));
1520         feather = new CWindowMaskFeather(mwindow,
1521                 this,
1522                 x + 110,
1523                 y);
1524         feather->create_objects();
1525         y += 30;
1526         add_subwindow(title = new BC_Title(x, y, _("X:")));
1527         x += title->get_w();
1528         this->x = new CWindowCoord(this, 
1529                 x, 
1530                 y, 
1531                 (float)0.0);
1532         this->x->create_objects();
1533         x += 150;
1534         add_subwindow(title = new BC_Title(x, y, _("Y:")));
1535         x += title->get_w();
1536         this->y = new CWindowCoord(this, 
1537                 x, 
1538                 y, 
1539                 (float)0.0);
1540         this->y->create_objects();
1541 //printf("CWindowMaskGUI::create_objects 1\n");
1543         update();
1544         if(mwindow->edl->session->tool_window) show_window();
1545         flush();
1546 //printf("CWindowMaskGUI::create_objects 2\n");
1549 void CWindowMaskGUI::get_keyframe(Track* &track, 
1550         MaskAuto* &keyframe, 
1551         SubMask* &mask, 
1552         MaskPoint* &point,
1553         int create_it)
1555         keyframe = 0;
1556         track = mwindow->cwindow->calculate_affected_track();
1557         if(track)
1558                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->mask_autos, create_it);
1559         else
1560                 keyframe = 0;
1562         if(keyframe)
1563                 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
1564         else
1565                 mask = 0;
1567         point = 0;
1568         if(keyframe)
1569         {
1570                 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
1571                         mwindow->cwindow->gui->affected_point >= 0)
1572                 {
1573                         point =  mask->points.values[mwindow->cwindow->gui->affected_point];
1574                 }
1575         }
1578 void CWindowMaskGUI::update()
1580         MaskAuto *keyframe;
1581         Track *track;
1582         MaskPoint *point;
1583         SubMask *mask;
1584 //printf("CWindowMaskGUI::update 1\n");
1585         get_keyframe(track, 
1586                 keyframe, 
1587                 mask,
1588                 point,
1589                 0);
1591 //printf("CWindowMaskGUI::update 1\n");
1592         if(point)
1593         {
1594                 x->update(point->x);
1595                 y->update(point->y);
1596         }
1597 //printf("CWindowMaskGUI::update 1\n");
1599         if(mask)
1600         {
1601                 feather->update((int64_t)keyframe->feather);
1602                 value->update((int64_t)keyframe->value);
1603         }
1604 //printf("CWindowMaskGUI::update 1\n");
1606         number->update((int64_t)mwindow->edl->session->cwindow_mask);
1608 //printf("CWindowMaskGUI::update 1\n");
1609         if(track)
1610         {
1611                 mode->set_text(
1612                         CWindowMaskMode::mode_to_text(((MaskAuto*)track->automation->mask_autos->default_auto)->mode));
1613         }
1614 //printf("CWindowMaskGUI::update 2\n");
1617 void CWindowMaskGUI::handle_event()
1619         MaskAuto *keyframe;
1620         Track *track;
1621         MaskPoint *point;
1622         SubMask *mask;
1623         get_keyframe(track, 
1624                 keyframe, 
1625                 mask,
1626                 point,
1627                 0);
1629         if(point)
1630         {
1631                 point->x = atof(x->get_text());
1632                 point->y = atof(y->get_text());
1633         }
1635         update_preview();
1638 void CWindowMaskGUI::update_preview()
1640         mwindow->restart_brender();
1641         mwindow->sync_parameters(CHANGE_PARAMS);
1642         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1643                         CHANGE_NONE,
1644                         mwindow->edl,
1645                         1);
1646         mwindow->cwindow->gui->lock_window();
1647         mwindow->cwindow->gui->canvas->draw_refresh();
1648         mwindow->cwindow->gui->unlock_window();