r602: Fix baver's code... don't insert timecode when show_tc is not set
[cinelerra_cv/mob.git] / cinelerra / cwindowtool.C
blob66468cadb46752df75ee4a1e1bbc43809c82daff
1 #include "automation.h"
2 #include "bezierauto.h"
3 #include "bezierautos.h"
4 #include "condition.h"
5 #include "cpanel.h"
6 #include "cplayback.h"
7 #include "cwindow.h"
8 #include "cwindowgui.h"
9 #include "cwindowtool.h"
10 #include "edl.h"
11 #include "edlsession.h"
12 #include "floatauto.h"
13 #include "floatautos.h"
14 #include "keys.h"
15 #include "language.h"
16 #include "localsession.h"
17 #include "mainsession.h"
18 #include "maskauto.h"
19 #include "maskautos.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_CROP:
65                                 new_gui = new CWindowCropGUI(mwindow, this);
66                                 break;
67                         case CWINDOW_CAMERA:
68                                 new_gui = new CWindowCameraGUI(mwindow, this);
69                                 break;
70                         case CWINDOW_PROJECTOR:
71                                 new_gui = new CWindowProjectorGUI(mwindow, this);
72                                 break;
73                         case CWINDOW_MASK:
74                                 new_gui = new CWindowMaskGUI(mwindow, this);
75                                 break;
76                         default:
77                                 result = 1;
78                                 stop_tool();
79                                 break;
80                 }
82 //printf("CWindowTool::start_tool 1\n");
85                 if(!result)
86                 {
87                         stop_tool();
88 // Wait for previous tool GUI to finish
89                         output_lock->lock("CWindowTool::start_tool");
90                         this->tool_gui = new_gui;
91                         tool_gui->create_objects();
92 // Signal thread to run next tool GUI
93                         input_lock->unlock();
94                 }
95 //printf("CWindowTool::start_tool 1\n");
96         }
97         else
98         if(tool_gui) 
99         {
100                 tool_gui->lock_window("CWindowTool::start_tool");
101                 tool_gui->update();
102                 tool_gui->unlock_window();
103         }
105 //printf("CWindowTool::start_tool 2\n");
110 void CWindowTool::stop_tool()
112         if(tool_gui)
113         {
114                 tool_gui->lock_window("CWindowTool::stop_tool");
115                 tool_gui->set_done(0);
116                 tool_gui->unlock_window();
117         }
120 void CWindowTool::run()
122         while(!done)
123         {
124                 input_lock->lock("CWindowTool::run");
125                 if(!done)
126                 {
127                         tool_gui->run_window();
128                         tool_gui_lock->lock("CWindowTool::run");
129                         delete tool_gui;
130                         tool_gui = 0;
131                         tool_gui_lock->unlock();
132                 }
133                 output_lock->unlock();
134         }
137 void CWindowTool::update_show_window()
139         if(tool_gui)
140         {
141                 tool_gui->lock_window("CWindowTool::update_show_window");
143                 if(mwindow->edl->session->tool_window) 
144                 {
145                         tool_gui->update();
146                         tool_gui->show_window();
147                 }
148                 else
149                         tool_gui->hide_window();
150                 tool_gui->flush();
152                 tool_gui->unlock_window();
153         }
156 void CWindowTool::update_values()
158         tool_gui_lock->lock("CWindowTool::update_values");
159         if(tool_gui)
160         {
161                 tool_gui->lock_window("CWindowTool::update_values");
162                 tool_gui->update();
163                 tool_gui->flush();
164                 tool_gui->unlock_window();
165         }
166         tool_gui_lock->unlock();
175 CWindowToolGUI::CWindowToolGUI(MWindow *mwindow, 
176         CWindowTool *thread, 
177         char *title,
178         int w, 
179         int h)
180  : BC_Window(title,
181         mwindow->session->ctool_x,
182         mwindow->session->ctool_y,
183         w,
184         h,
185         w,
186         h,
187         0,
188         0,
189         1)
191         this->mwindow = mwindow;
192         this->thread = thread;
193         current_operation = 0;
196 CWindowToolGUI::~CWindowToolGUI()
200 int CWindowToolGUI::close_event()
202         hide_window();
203         flush();
204         mwindow->edl->session->tool_window = 0;
205         thread->gui->lock_window("CWindowToolGUI::close_event");
206         thread->gui->composite_panel->set_operation(mwindow->edl->session->cwindow_operation);
207         thread->gui->flush();
208         thread->gui->unlock_window();
209         return 1;
212 int CWindowToolGUI::keypress_event()
214         if(get_keypress() == 'w' || get_keypress() == 'W')
215                 return close_event();
216         return 0;
219 int CWindowToolGUI::translation_event()
221         mwindow->session->ctool_x = get_x();
222         mwindow->session->ctool_y = get_y();
223         return 0;
231 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value)
232  : BC_TumbleTextBox(gui, 
233                 (float)value,
234                 (float)-65536,
235                 (float)65536,
236                 x, 
237                 y, 
238                 100)
240         this->gui = gui;
243 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
244  : BC_TumbleTextBox(gui, 
245                 (int64_t)value,
246                 (int64_t)-65536,
247                 (int64_t)65536,
248                 x, 
249                 y, 
250                 100)
252         this->gui = gui;
254 int CWindowCoord::handle_event()
256         gui->event_caller = this;
257         gui->handle_event();
258         return 1;
262 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
263  : BC_GenericButton(x, y, _("Do it"))
265         this->mwindow = mwindow;
266         this->gui = gui;
268 int CWindowCropOK::handle_event()
270         mwindow->crop_video();
271         return 1;
275 int CWindowCropOK::keypress_event()
277         if(get_keypress() == 0xd) 
278         {
279                 handle_event();
280                 return 1;
281         }
282         return 0;
291 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
292  : CWindowToolGUI(mwindow, 
293         thread,
294         PROGRAM_NAME ": Crop",
295         330,
296         100)
301 CWindowCropGUI::~CWindowCropGUI()
305 void CWindowCropGUI::create_objects()
307         int x = 10, y = 10;
308         BC_TumbleTextBox *textbox;
309         BC_Title *title;
311         add_subwindow(title = new BC_Title(x, y, _("X1:")));
312         x += title->get_w();
313         x1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_x1);
314         x1->create_objects();
315         x += x1->get_w() + 10;
317         add_subwindow(title = new BC_Title(x, y, _("Y1:")));
318         x += title->get_w();
319         y1 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_y1);
320         y1->create_objects();
321         y += y1->get_h() + 5;
322         x = 10;
324         add_subwindow(title = new BC_Title(x, y, _("X2:")));
325         x += title->get_w();
326         x2 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_x2);
327         x2->create_objects();
328         x += x2->get_w() + 10;
330         add_subwindow(title = new BC_Title(x, y, _("Y2:")));
331         x += title->get_w();
332         y2 = new CWindowCoord(thread->tool_gui, x, y, mwindow->edl->session->crop_y2);
333         y2->create_objects();
334         y += y2->get_h() + 5;
335         x = 10;
336         add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
338         if(mwindow->edl->session->tool_window) show_window();
339         flush();
342 void CWindowCropGUI::handle_event()
344         mwindow->edl->session->crop_x1 = atol(x1->get_text());
345         mwindow->edl->session->crop_y1 = atol(y1->get_text());
346         mwindow->edl->session->crop_x2 = atol(x2->get_text());
347         mwindow->edl->session->crop_y2 = atol(y2->get_text());
348         mwindow->cwindow->gui->lock_window("CWindowCropGUI::handle_event");
349         mwindow->cwindow->gui->canvas->draw_refresh();
350         mwindow->cwindow->gui->unlock_window();
353 void CWindowCropGUI::update()
355         x1->update((int64_t)mwindow->edl->session->crop_x1);
356         y1->update((int64_t)mwindow->edl->session->crop_y1);
357         x2->update((int64_t)mwindow->edl->session->crop_x2);
358         y2->update((int64_t)mwindow->edl->session->crop_y2);
372 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
373  : CWindowToolGUI(mwindow, 
374         thread,
375         PROGRAM_NAME ": Camera",
376         170,
377         170)
380 CWindowCameraGUI::~CWindowCameraGUI()
384 void CWindowCameraGUI::create_objects()
386         int x = 10, y = 10, x1;
387         Track *track = mwindow->cwindow->calculate_affected_track();
388         BezierAuto *keyframe = 0;
389         FloatAuto *zoom_keyframe = 0;
390         BC_Title *title;
391         BC_Button *button;
393         if(track)
394         {
395                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
396                         track->automation->camera_autos, 
397                         0);
398                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
399                         track->automation->czoom_autos, 
400                         0);
401         }
403         add_subwindow(title = new BC_Title(x, y, _("X:")));
404         x += title->get_w();
405         this->x = new CWindowCoord(this, 
406                 x, 
407                 y, 
408                 keyframe ? keyframe->center_x : (float)0);
409         this->x->create_objects();
410         y += 30;
411         x = 10;
412         add_subwindow(title = new BC_Title(x, y, _("Y:")));
413         x += title->get_w();
414         this->y = new CWindowCoord(this, 
415                 x, 
416                 y, 
417                 keyframe ? keyframe->center_y : (float)0);
418         this->y->create_objects();
419         y += 30;
420         x = 10;
421         add_subwindow(title = new BC_Title(x, y, _("Z:")));
422         x += title->get_w();
423         this->z = new CWindowCoord(this, 
424                 x, 
425                 y, 
426                 zoom_keyframe ? zoom_keyframe->value : (float)1);
427         this->z->create_objects();
429         y += 30;
430         x1 = 10;
431         add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
432         x1 += button->get_w();
433         add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
434         x1 += button->get_w();
435         add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
437         y += button->get_h();
438         x1 = 10;
439         add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
440         x1 += button->get_w();
441         add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
442         x1 += button->get_w();
443         add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
447         if(mwindow->edl->session->tool_window) show_window();
448         flush();
451 void CWindowCameraGUI::update_preview()
453         mwindow->restart_brender();
454         mwindow->sync_parameters(CHANGE_PARAMS);
456         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
457                         CHANGE_NONE,
458                         mwindow->edl,
459                         1);
460         mwindow->cwindow->gui->lock_window("CWindowCameraGUI::update_preview");
461         mwindow->cwindow->gui->canvas->draw_refresh();
462         mwindow->cwindow->gui->unlock_window();
466 void CWindowCameraGUI::handle_event()
468         BezierAuto *keyframe = 0;
469         FloatAuto *zoom_keyframe = 0;
470         Track *track = mwindow->cwindow->calculate_affected_track();
471         if(track)
472         {
473                 if(event_caller == z)
474                         zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
475                                 track->automation->czoom_autos,
476                                 1);
477                 else
478                         keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
479                                 track->automation->camera_autos,
480                                 1);
481         }
483         if(keyframe)
484         {
485                 keyframe->center_x = atof(x->get_text());
486                 keyframe->center_y = atof(y->get_text());
487                 update_preview();
488         }
489         else
490         if(zoom_keyframe)
491         {
492                 float zoom = atof(z->get_text());
493                 if(zoom > 10) zoom = 10; 
494                 else
495                 if(zoom < 0) zoom = 0;
496 // Doesn't allow user to enter from scratch
497 //              if(zoom != atof(z->get_text())) 
498 //                      z->update(zoom);
500                 zoom_keyframe->value = zoom;
501                 mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
502                 mwindow->gui->canvas->draw_overlays();
503                 mwindow->gui->canvas->flash();
504                 mwindow->gui->unlock_window();
505                 update_preview();
506         }
509 void CWindowCameraGUI::update()
511         BezierAuto *keyframe = 0;
512         FloatAuto *zoom_keyframe = 0;
513         Track *track = mwindow->cwindow->calculate_affected_track();
515         if(track)
516         {
517                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
518                         track->automation->camera_autos, 
519                         0);
520                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
521                         track->automation->czoom_autos, 
522                         0);
523         }
525         if(keyframe)
526         {
527                 x->update(keyframe->center_x);
528                 y->update(keyframe->center_y);
529         }
531         if(zoom_keyframe)
532         {
533                 z->update(zoom_keyframe->value);
534         }
537 BezierAuto* CWindowCameraGUI::get_keyframe()
539         BezierAuto *keyframe = 0;
540         Track *track = mwindow->cwindow->calculate_affected_track();
541         if(track)
542                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
543         return keyframe;
548 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
549  : BC_Button(x, y, mwindow->theme->left_justify)
551         this->gui = gui;
552         this->mwindow = mwindow;
553         set_tooltip(_("Left justify"));
555 int CWindowCameraLeft::handle_event()
557         BezierAuto *keyframe = 0;
558         FloatAuto *zoom_keyframe = 0;
559         Track *track = mwindow->cwindow->calculate_affected_track();
560         if(track)
561         {
562                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos, 1);
563                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->czoom_autos, 0);
564         }
566         if(keyframe)
567         {
568                 int w = 0, h = 0;
569                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
570                         w,
571                         h);
573                 if(w && h)
574                 {
575                         keyframe->center_x = 
576                                 (double)track->track_w / zoom_keyframe->value / 2 - 
577                                 (double)w / 2;
578                         gui->update();
579                         gui->update_preview();
580                 }
581         }
583         return 1;
587 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
588  : BC_Button(x, y, mwindow->theme->center_justify)
590         this->gui = gui;
591         this->mwindow = mwindow;
592         set_tooltip(_("Center horizontal"));
594 int CWindowCameraCenter::handle_event()
596         BezierAuto *keyframe = 0;
597         Track *track = mwindow->cwindow->calculate_affected_track();
598         if(track)
599                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
601         if(keyframe)
602         {
603                 keyframe->center_x = 0;
604                 gui->update();
605                 gui->update_preview();
606         }
608         return 1;
612 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
613  : BC_Button(x, y, mwindow->theme->right_justify)
615         this->gui = gui;
616         this->mwindow = mwindow;
617         set_tooltip(_("Right justify"));
619 int CWindowCameraRight::handle_event()
621         BezierAuto *keyframe = 0;
622         FloatAuto *zoom_keyframe = 0;
623         Track *track = mwindow->cwindow->calculate_affected_track();
624         if(track)
625         {
626                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos, 1);
627                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->czoom_autos, 0);
628         }
630         if(keyframe)
631         {
632                 int w = 0, h = 0;
633                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
634                         w,
635                         h);
637                 if(w && h)
638                 {
639                         keyframe->center_x = -((double)track->track_w / zoom_keyframe->value / 2 - 
640                                 (double)w / 2);
641                         gui->update();
642                         gui->update_preview();
643                 }
644         }
646         return 1;
650 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
651  : BC_Button(x, y, mwindow->theme->top_justify)
653         this->gui = gui;
654         this->mwindow = mwindow;
655         set_tooltip(_("Top justify"));
657 int CWindowCameraTop::handle_event()
659         BezierAuto *keyframe = 0;
660         FloatAuto *zoom_keyframe = 0;
661         Track *track = mwindow->cwindow->calculate_affected_track();
662         if(track)
663         {
664                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos, 1);
665                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->czoom_autos, 0);
666         }
668         if(keyframe)
669         {
670                 int w = 0, h = 0;
671                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
672                         w,
673                         h);
675                 if(w && h)
676                 {
677                         keyframe->center_y = (double)track->track_h / zoom_keyframe->value / 2 - 
678                                 (double)h / 2;
679                         gui->update();
680                         gui->update_preview();
681                 }
682         }
684         return 1;
688 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
689  : BC_Button(x, y, mwindow->theme->middle_justify)
691         this->gui = gui;
692         this->mwindow = mwindow;
693         set_tooltip(_("Center vertical"));
695 int CWindowCameraMiddle::handle_event()
697         BezierAuto *keyframe = 0;
698         Track *track = mwindow->cwindow->calculate_affected_track();
699         if(track)
700                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos);
702         if(keyframe)
703         {
704                 keyframe->center_y = 0;
705                 gui->update();
706                 gui->update_preview();
707         }
709         return 1;
713 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
714  : BC_Button(x, y, mwindow->theme->bottom_justify)
716         this->gui = gui;
717         this->mwindow = mwindow;
718         set_tooltip(_("Bottom justify"));
720 int CWindowCameraBottom::handle_event()
722         BezierAuto *keyframe = 0;
723         FloatAuto *zoom_keyframe = 0;
724         Track *track = mwindow->cwindow->calculate_affected_track();
725         if(track)
726         {
727                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->camera_autos, 1);
728                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->czoom_autos, 0);
729         }
731         if(keyframe)
732         {
733                 int w = 0, h = 0;
734                 track->get_source_dimensions(mwindow->edl->local_session->selectionstart,
735                         w,
736                         h);
738                 if(w && h)
739                 {
740                         keyframe->center_y = -((double)track->track_h / zoom_keyframe->value / 2 - 
741                                 (double)h / 2);
742                         gui->update();
743                         gui->update_preview();
744                 }
745         }
747         return 1;
766 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
767  : CWindowToolGUI(mwindow, 
768         thread,
769         PROGRAM_NAME ": Projector",
770         170,
771         170)
774 CWindowProjectorGUI::~CWindowProjectorGUI()
777 void CWindowProjectorGUI::create_objects()
779         int x = 10, y = 10, x1;
780         Track *track = mwindow->cwindow->calculate_affected_track();
781         BezierAuto *keyframe = 0;
782         FloatAuto *zoom_keyframe = 0;
783         BC_Title *title;
784         BC_Button *button;
786         if(track)
787         {
788                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
789                         track->automation->projector_autos, 
790                         0);
791                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
792                         track->automation->pzoom_autos, 
793                         0);
794         }
796         add_subwindow(title = new BC_Title(x, y, _("X:")));
797         x += title->get_w();
798         this->x = new CWindowCoord(this, 
799                 x, 
800                 y, 
801                 keyframe ? keyframe->center_x : (float)0);
802         this->x->create_objects();
803         y += 30;
804         x = 10;
805         add_subwindow(title = new BC_Title(x, y, _("Y:")));
806         x += title->get_w();
807         this->y = new CWindowCoord(this, 
808                 x, 
809                 y, 
810                 keyframe ? keyframe->center_y : (float)0);
811         this->y->create_objects();
812         y += 30;
813         x = 10;
814         add_subwindow(title = new BC_Title(x, y, _("Z:")));
815         x += title->get_w();
816         this->z = new CWindowCoord(this, 
817                 x, 
818                 y, 
819                 zoom_keyframe ? zoom_keyframe->value : (float)1);
820         this->z->create_objects();
822         y += 30;
823         x1 = 10;
824         add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
825         x1 += button->get_w();
826         add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
827         x1 += button->get_w();
828         add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
830         y += button->get_h();
831         x1 = 10;
832         add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
833         x1 += button->get_w();
834         add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
835         x1 += button->get_w();
836         add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
839         if(mwindow->edl->session->tool_window) show_window();
840         flush();
843 void CWindowProjectorGUI::update_preview()
845         mwindow->restart_brender();
846         mwindow->sync_parameters(CHANGE_PARAMS);
847         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
848                         CHANGE_NONE,
849                         mwindow->edl,
850                         1);
851         mwindow->cwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
852         mwindow->cwindow->gui->canvas->draw_refresh();
853         mwindow->cwindow->gui->unlock_window();
856 void CWindowProjectorGUI::handle_event()
858         BezierAuto *keyframe = 0;
859         FloatAuto *zoom_keyframe = 0;
860         Track *track = mwindow->cwindow->calculate_affected_track();
862         if(track)
863         {
864                 if(event_caller == z)
865                         zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
866                                 track->automation->pzoom_autos,
867                                 1);
868                 else
869                         keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
870                                 track->automation->projector_autos,
871                                 1);
872         }
874         if(keyframe)
875         {
876                 keyframe->center_x = atof(x->get_text());
877                 keyframe->center_y = atof(y->get_text());
878                 update_preview();
879         }
880         else
881         if(zoom_keyframe)
882         {
883                 float zoom = atof(z->get_text());
884                 if(zoom > 10000) zoom = 10000; 
885                 else 
886                 if(zoom < 0) zoom = 0;
887 //              if (zoom != atof(z->get_text())) 
888 //                      z->update(zoom);
889                 zoom_keyframe->value = zoom;
890                 mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
891                 mwindow->gui->canvas->draw_overlays();
892                 mwindow->gui->canvas->flash();
893                 mwindow->gui->unlock_window();
894                 update_preview();
895         }
898 void CWindowProjectorGUI::update()
900         BezierAuto *keyframe = 0;
901         FloatAuto *zoom_keyframe = 0;
902         Track *track = mwindow->cwindow->calculate_affected_track();
904         if(track)
905         {
906                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(
907                         track->automation->projector_autos, 
908                         0);
909                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
910                         track->automation->pzoom_autos, 
911                         0);
912         }
914         if(keyframe)
915         {
916                 x->update(keyframe->center_x);
917                 y->update(keyframe->center_y);
918         }
920         if(zoom_keyframe)
921         {
922                 z->update(zoom_keyframe->value);
923         }
926 BezierAuto* CWindowProjectorGUI::get_keyframe()
928         BezierAuto *keyframe = 0;
929         Track *track = mwindow->cwindow->calculate_affected_track();
930         if(track)
931                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
932         return keyframe;
972 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
973  : BC_Button(x, y, mwindow->theme->left_justify)
975         this->gui = gui;
976         this->mwindow = mwindow;
977         set_tooltip(_("Left justify"));
979 int CWindowProjectorLeft::handle_event()
981         BezierAuto *keyframe = 0;
982         FloatAuto *zoom_keyframe = 0;
983         Track *track = mwindow->cwindow->calculate_affected_track();
984         if(track)
985         {
986                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos, 1);
987                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->pzoom_autos, 0);
988         }
989         if(keyframe)
990         {
991                 keyframe->center_x = (double)track->track_w * zoom_keyframe->value / 2 - 
992                         (double)mwindow->edl->session->output_w / 2;
993                 gui->update();
994                 gui->update_preview();
995         }
997         return 1;
1001 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1002  : BC_Button(x, y, mwindow->theme->center_justify)
1004         this->gui = gui;
1005         this->mwindow = mwindow;
1006         set_tooltip(_("Center horizontal"));
1008 int CWindowProjectorCenter::handle_event()
1010         BezierAuto *keyframe = 0;
1011         Track *track = mwindow->cwindow->calculate_affected_track();
1012         if(track)
1013                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
1015         if(keyframe)
1016         {
1017                 keyframe->center_x = 0;
1018                 gui->update();
1019                 gui->update_preview();
1020         }
1022         return 1;
1026 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1027  : BC_Button(x, y, mwindow->theme->right_justify)
1029         this->gui = gui;
1030         this->mwindow = mwindow;
1031         set_tooltip(_("Right justify"));
1033 int CWindowProjectorRight::handle_event()
1035         BezierAuto *keyframe = 0;
1036         FloatAuto *zoom_keyframe = 0;
1037         Track *track = mwindow->cwindow->calculate_affected_track();
1038         if(track)
1039         {
1040                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos, 1);
1041                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->pzoom_autos, 0);
1042         }
1044         if(keyframe)
1045         {
1046                 keyframe->center_x = -((double)track->track_w * zoom_keyframe->value / 2 - 
1047                         (double)mwindow->edl->session->output_w / 2);
1048                 gui->update();
1049                 gui->update_preview();
1050         }
1052         return 1;
1056 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1057  : BC_Button(x, y, mwindow->theme->top_justify)
1059         this->gui = gui;
1060         this->mwindow = mwindow;
1061         set_tooltip(_("Top justify"));
1063 int CWindowProjectorTop::handle_event()
1065         BezierAuto *keyframe = 0;
1066         FloatAuto *zoom_keyframe = 0;
1067         Track *track = mwindow->cwindow->calculate_affected_track();
1068         if(track)
1069         {
1070                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos, 1);
1071                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->pzoom_autos, 0);
1072         }
1074         if(keyframe)
1075         {
1076                 keyframe->center_y = (double)track->track_h * zoom_keyframe->value / 2 - 
1077                         (double)mwindow->edl->session->output_h / 2;
1078                 gui->update();
1079                 gui->update_preview();
1080         }
1082         return 1;
1086 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1087  : BC_Button(x, y, mwindow->theme->middle_justify)
1089         this->gui = gui;
1090         this->mwindow = mwindow;
1091         set_tooltip(_("Center vertical"));
1093 int CWindowProjectorMiddle::handle_event()
1095         BezierAuto *keyframe = 0;
1096         Track *track = mwindow->cwindow->calculate_affected_track();
1097         if(track)
1098                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos);
1100         if(keyframe)
1101         {
1102                 keyframe->center_y = 0;
1103                 gui->update();
1104                 gui->update_preview();
1105         }
1107         return 1;
1111 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1112  : BC_Button(x, y, mwindow->theme->bottom_justify)
1114         this->gui = gui;
1115         this->mwindow = mwindow;
1116         set_tooltip(_("Bottom justify"));
1118 int CWindowProjectorBottom::handle_event()
1120         BezierAuto *keyframe = 0;
1121         FloatAuto *zoom_keyframe = 0;
1122         Track *track = mwindow->cwindow->calculate_affected_track();
1123         if(track)
1124         {
1125                 keyframe = (BezierAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->projector_autos, 1);
1126                 zoom_keyframe = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->pzoom_autos, 0);
1127         }
1129         if(keyframe)
1130         {
1131                 keyframe->center_y = -((double)track->track_h * zoom_keyframe->value / 2 - 
1132                         (double)mwindow->edl->session->output_h / 2);
1133                 gui->update();
1134                 gui->update_preview();
1135         }
1137         return 1;
1147 CWindowMaskMode::CWindowMaskMode(MWindow *mwindow, 
1148         CWindowToolGUI *gui, 
1149         int x, 
1150         int y,
1151         char *text)
1152  : BC_PopupMenu(x,
1153         y,
1154         200,
1155         text,
1156         1)
1158         this->mwindow = mwindow;
1159         this->gui = gui;
1162 void CWindowMaskMode::create_objects()
1164         add_item(new BC_MenuItem(mode_to_text(MASK_MULTIPLY_ALPHA)));
1165         add_item(new BC_MenuItem(mode_to_text(MASK_SUBTRACT_ALPHA)));
1168 char* CWindowMaskMode::mode_to_text(int mode)
1170         switch(mode)
1171         {
1172                 case MASK_MULTIPLY_ALPHA:
1173                         return _("Multiply alpha");
1174                         break;
1175                 
1176                 case MASK_SUBTRACT_ALPHA:
1177                         return _("Subtract alpha");
1178                         break;
1179         }
1181         return _("Subtract alpha");
1184 int CWindowMaskMode::text_to_mode(char *text)
1186         if(!strcasecmp(text, _("Multiply alpha")))
1187                 return MASK_MULTIPLY_ALPHA;
1188         else
1189         if(!strcasecmp(text, _("Subtract alpha")))
1190                 return MASK_SUBTRACT_ALPHA;
1192         return MASK_SUBTRACT_ALPHA;
1195 int CWindowMaskMode::handle_event()
1197         MaskAuto *keyframe;
1198         Track *track;
1199         MaskPoint *point;
1200         SubMask *mask;
1201         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1202                 keyframe, 
1203                 mask,
1204                 point,
1205                 0);
1207         if(track)
1208         {
1209                 ((MaskAuto*)track->automation->mask_autos->default_auto)->mode = 
1210                         text_to_mode(get_text());
1211         }
1213 //printf("CWindowMaskMode::handle_event 1\n");
1214         gui->update_preview();
1215         return 1;
1225 CWindowMaskDelete::CWindowMaskDelete(MWindow *mwindow, 
1226         CWindowToolGUI *gui, 
1227         int x, 
1228         int y)
1229  : BC_GenericButton(x, y, _("Delete"))
1231         this->mwindow = mwindow;
1232         this->gui = gui;
1235 int CWindowMaskDelete::handle_event()
1237         MaskAuto *keyframe;
1238         Track *track = mwindow->cwindow->calculate_affected_track();
1239         MaskPoint *point;
1240         SubMask *mask;
1243         if(track)
1244         {
1245                 MaskAutos *mask_autos = track->automation->mask_autos;
1246                 for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto;
1247                         current; )
1248                 {
1249                         SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1252                         
1253                         for(int i = mwindow->cwindow->gui->affected_point;
1254                                 i < submask->points.total - 1;
1255                                 i++)
1256                         {
1257                                 *submask->points.values[i] = *submask->points.values[i + 1];
1258                         }
1260                         if(submask->points.total)
1261                         {
1262                                 submask->points.remove_object(
1263                                         submask->points.values[submask->points.total - 1]);
1264                         }
1267                         if(current == (MaskAuto*)mask_autos->default_auto)
1268                                 current = (MaskAuto*)mask_autos->first;
1269                         else
1270                                 current = (MaskAuto*)NEXT;
1271                 }
1272                 gui->update();
1273                 gui->update_preview();
1274         }
1277 //      ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1278 //              keyframe, 
1279 //              mask, 
1280 //              point,
1281 //              0);
1283 // Need to apply to every keyframe
1284         
1285 //      if(keyframe)
1286 //      {
1287 //              for(int i = mwindow->cwindow->gui->affected_point;
1288 //                      i < mask->points.total - 1;
1289 //                      i++)
1290 //              {
1291 //                      *mask->points.values[i] = *mask->points.values[i + 1];
1292 //              }
1293 //              
1294 //              if(mask->points.total)
1295 //              {
1296 //                      mask->points.remove_object(mask->points.values[mask->points.total - 1]);
1297 //              }
1298 // 
1299 //              gui->update();
1300 //              gui->update_preview();
1301 //      }
1303         return 1;
1306 int CWindowMaskDelete::keypress_event()
1308         if(get_keypress() == BACKSPACE ||
1309                 get_keypress() == DELETE) 
1310                 return handle_event();
1311         return 0;
1315 CWindowMaskCycleNext::CWindowMaskCycleNext(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1316  : BC_GenericButton(x, y, _("Cycle next"))
1318         this->mwindow = mwindow;
1319         this->gui = gui;
1321 int CWindowMaskCycleNext::handle_event()
1323         MaskAuto *keyframe;
1324         Track *track;
1325         MaskPoint *point;
1326         SubMask *mask;
1327         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1328                 keyframe,
1329                 mask,  
1330                 point,
1331                 0);
1333         MaskPoint *temp;
1335 // Should apply to all keyframes
1336         if(keyframe && mask->points.total)
1337         {
1338                 temp = mask->points.values[0];
1340                 for(int i = 0; i < mask->points.total - 1; i++)
1341                 {
1342                         mask->points.values[i] = mask->points.values[i + 1];
1343                 }
1344                 mask->points.values[mask->points.total - 1] = temp;
1346                 mwindow->cwindow->gui->affected_point--;
1347                 if(mwindow->cwindow->gui->affected_point < 0)
1348                         mwindow->cwindow->gui->affected_point = mask->points.total - 1;
1350                 gui->update();
1351                 gui->update_preview();
1352         }
1353         
1354         return 1;
1357 CWindowMaskCyclePrev::CWindowMaskCyclePrev(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1358  : BC_GenericButton(x, y, _("Cycle prev"))
1360         this->mwindow = mwindow;
1361         this->gui = gui;
1363 int CWindowMaskCyclePrev::handle_event()
1365         MaskAuto *keyframe;
1366         Track *track;
1367         MaskPoint *point;
1368         SubMask *mask;
1369         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1370                 keyframe,
1371                 mask, 
1372                 point,
1373                 0);
1375 // Should apply to all keyframes
1376         MaskPoint *temp;
1377         if(keyframe && mask->points.total)
1378         {
1379                 temp = mask->points.values[mask->points.total - 1];
1381                 for(int i = mask->points.total - 1; i > 0; i--)
1382                 {
1383                         mask->points.values[i] = mask->points.values[i - 1];
1384                 }
1385                 mask->points.values[0] = temp;
1387                 mwindow->cwindow->gui->affected_point++;
1388                 if(mwindow->cwindow->gui->affected_point >= mask->points.total)
1389                         mwindow->cwindow->gui->affected_point = 0;
1391                 gui->update();
1392                 gui->update_preview();
1393         }
1394         return 1;
1398 CWindowMaskNumber::CWindowMaskNumber(MWindow *mwindow, 
1399         CWindowToolGUI *gui, 
1400         int x, 
1401         int y)
1402  : BC_TumbleTextBox(gui, 
1403                 (int64_t)mwindow->edl->session->cwindow_mask,
1404                 (int64_t)0,
1405                 (int64_t)SUBMASKS - 1,
1406                 x, 
1407                 y, 
1408                 100)
1410         this->mwindow = mwindow;
1411         this->gui = gui;
1414 CWindowMaskNumber::~CWindowMaskNumber()
1418 int CWindowMaskNumber::handle_event()
1420         mwindow->edl->session->cwindow_mask = atol(get_text());
1421         gui->update();
1422         gui->update_preview();
1423         return 1;
1430 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1431  : BC_TumbleTextBox(gui, 
1432                 (int64_t)0,
1433                 (int64_t)0,
1434                 (int64_t)0xff,
1435                 x, 
1436                 y, 
1437                 100)
1439         this->mwindow = mwindow;
1440         this->gui = gui;
1442 CWindowMaskFeather::~CWindowMaskFeather()
1445 int CWindowMaskFeather::handle_event()
1447         MaskAuto *keyframe;
1448         Track *track;
1449         MaskPoint *point;
1450         SubMask *mask;
1451         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1452                 keyframe,
1453                 mask, 
1454                 point,
1455                 1);
1457         keyframe->feather = atof(get_text());
1458         gui->update_preview();
1459         return 1;
1462 CWindowMaskValue::CWindowMaskValue(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1463  : BC_ISlider(x, 
1464                         y,
1465                         0,
1466                         200, 
1467                         200, 
1468                         0, 
1469                         100, 
1470                         0)
1472         this->mwindow = mwindow;
1473         this->gui = gui;
1476 CWindowMaskValue::~CWindowMaskValue()
1480 int CWindowMaskValue::handle_event()
1482         MaskAuto *keyframe;
1483         Track *track;
1484         MaskPoint *point;
1485         SubMask *mask;
1486         ((CWindowMaskGUI*)gui)->get_keyframe(track, 
1487                 keyframe,
1488                 mask, 
1489                 point,
1490                 1);
1492         keyframe->value = get_value();
1493         gui->update_preview();
1494         return 1;
1507 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
1508  : CWindowToolGUI(mwindow, 
1509         thread,
1510         PROGRAM_NAME ": Mask",
1511         330,
1512         280)
1514         this->mwindow = mwindow;
1515         this->thread = thread;
1517 CWindowMaskGUI::~CWindowMaskGUI()
1519         delete number;
1520         delete feather;
1523 void CWindowMaskGUI::create_objects()
1525 //printf("CWindowMaskGUI::create_objects 1\n");
1526         int x = 10, y = 10;
1527         MaskAuto *keyframe = 0;
1528         Track *track = mwindow->cwindow->calculate_affected_track();
1529         if(track)
1530                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->mask_autos, 0);
1531 //printf("CWindowMaskGUI::create_objects 1\n");
1533         BC_Title *title;
1534         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
1535         add_subwindow(mode = new CWindowMaskMode(mwindow, 
1536                 this, 
1537                 x + title->get_w(), 
1538                 y,
1539                 ""));
1540 //printf("CWindowMaskGUI::create_objects 1\n");
1541         mode->create_objects();
1542         y += 40;
1543         add_subwindow(new BC_Title(x, y, _("Value:")));
1544         add_subwindow(value = new CWindowMaskValue(mwindow, this, x + 50, y));
1545         y += 30;
1546         add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
1547         y += 30;
1548 //      add_subwindow(next_point = new CWindowMaskCycleNext(mwindow, this, x, y));
1549 //      y += 30;
1550 //      add_subwindow(prev_point = new CWindowMaskCyclePrev(mwindow, this, x, y));
1551 //      y += 40;
1552         add_subwindow(new BC_Title(x, y, _("Mask number:")));
1553         number = new CWindowMaskNumber(mwindow, 
1554                 this, 
1555                 x + 110, 
1556                 y);
1557 //printf("CWindowMaskGUI::create_objects 1\n");
1558         number->create_objects();
1559         y += 30;
1560         add_subwindow(new BC_Title(x, y, _("Feather:")));
1561         feather = new CWindowMaskFeather(mwindow,
1562                 this,
1563                 x + 110,
1564                 y);
1565         feather->create_objects();
1566         y += 30;
1567         add_subwindow(title = new BC_Title(x, y, _("X:")));
1568         x += title->get_w();
1569         this->x = new CWindowCoord(this, 
1570                 x, 
1571                 y, 
1572                 (float)0.0);
1573         this->x->create_objects();
1574         x += 150;
1575         add_subwindow(title = new BC_Title(x, y, _("Y:")));
1576         x += title->get_w();
1577         this->y = new CWindowCoord(this, 
1578                 x, 
1579                 y, 
1580                 (float)0.0);
1581         this->y->create_objects();
1582 //printf("CWindowMaskGUI::create_objects 1\n");
1584         update();
1585         if(mwindow->edl->session->tool_window) show_window();
1586         flush();
1587 //printf("CWindowMaskGUI::create_objects 2\n");
1590 void CWindowMaskGUI::get_keyframe(Track* &track, 
1591         MaskAuto* &keyframe, 
1592         SubMask* &mask, 
1593         MaskPoint* &point,
1594         int create_it)
1596         keyframe = 0;
1597         track = mwindow->cwindow->calculate_affected_track();
1598         if(track)
1599                 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->mask_autos, create_it);
1600         else
1601                 keyframe = 0;
1603         if(keyframe)
1604                 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
1605         else
1606                 mask = 0;
1608         point = 0;
1609         if(keyframe)
1610         {
1611                 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
1612                         mwindow->cwindow->gui->affected_point >= 0)
1613                 {
1614                         point =  mask->points.values[mwindow->cwindow->gui->affected_point];
1615                 }
1616         }
1619 void CWindowMaskGUI::update()
1621         MaskAuto *keyframe;
1622         Track *track;
1623         MaskPoint *point;
1624         SubMask *mask;
1625 //printf("CWindowMaskGUI::update 1\n");
1626         get_keyframe(track, 
1627                 keyframe, 
1628                 mask,
1629                 point,
1630                 0);
1632 //printf("CWindowMaskGUI::update 1\n");
1633         if(point)
1634         {
1635                 x->update(point->x);
1636                 y->update(point->y);
1637         }
1638 //printf("CWindowMaskGUI::update 1\n");
1640         if(mask)
1641         {
1642                 feather->update((int64_t)keyframe->feather);
1643                 value->update((int64_t)keyframe->value);
1644         }
1645 //printf("CWindowMaskGUI::update 1\n");
1647         number->update((int64_t)mwindow->edl->session->cwindow_mask);
1649 //printf("CWindowMaskGUI::update 1\n");
1650         if(track)
1651         {
1652                 mode->set_text(
1653                         CWindowMaskMode::mode_to_text(((MaskAuto*)track->automation->mask_autos->default_auto)->mode));
1654         }
1655 //printf("CWindowMaskGUI::update 2\n");
1658 void CWindowMaskGUI::handle_event()
1660         MaskAuto *keyframe;
1661         Track *track;
1662         MaskPoint *point;
1663         SubMask *mask;
1664         get_keyframe(track, 
1665                 keyframe, 
1666                 mask,
1667                 point,
1668                 0);
1670         if(point)
1671         {
1672                 point->x = atof(x->get_text());
1673                 point->y = atof(y->get_text());
1674         }
1676         update_preview();
1679 void CWindowMaskGUI::update_preview()
1681         mwindow->restart_brender();
1682         mwindow->sync_parameters(CHANGE_PARAMS);
1683         mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
1684                         CHANGE_NONE,
1685                         mwindow->edl,
1686                         1);
1687         mwindow->cwindow->gui->lock_window("CWindowMaskGUI::update_preview");
1688         mwindow->cwindow->gui->canvas->draw_refresh();
1689         mwindow->cwindow->gui->unlock_window();