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