3 * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
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.
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.
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
24 #include "automation.h"
27 #include "condition.h"
29 #include "cplayback.h"
31 #include "cwindowgui.h"
32 #include "cwindowtool.h"
34 #include "edlsession.h"
35 #include "floatauto.h"
36 #include "floatautos.h"
39 #include "localsession.h"
40 #include "mainsession.h"
43 #include "maskautos.h"
46 #include "mwindowgui.h"
49 #include "trackcanvas.h"
50 #include "transportque.h"
53 CWindowTool::CWindowTool(MWindow *mwindow, CWindowGUI *gui)
56 this->mwindow = mwindow;
60 current_tool = CWINDOW_NONE;
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");
67 CWindowTool::~CWindowTool()
78 void CWindowTool::start_tool(int operation)
80 CWindowToolGUI *new_gui = 0;
83 //printf("CWindowTool::start_tool 1\n");
84 if(current_tool != operation)
86 current_tool = operation;
90 new_gui = new CWindowEyedropGUI(mwindow, this);
93 new_gui = new CWindowCropGUI(mwindow, this);
96 new_gui = new CWindowCameraGUI(mwindow, this);
98 case CWINDOW_PROJECTOR:
99 new_gui = new CWindowProjectorGUI(mwindow, this);
102 new_gui = new CWindowMaskGUI(mwindow, this);
105 new_gui = new CWindowRulerGUI(mwindow, this);
113 //printf("CWindowTool::start_tool 1\n");
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();
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");
128 tool_gui->unlock_window();
131 // Signal thread to run next tool GUI
132 input_lock->unlock();
134 //printf("CWindowTool::start_tool 1\n");
139 tool_gui->lock_window("CWindowTool::start_tool");
141 tool_gui->unlock_window();
144 //printf("CWindowTool::start_tool 2\n");
149 void CWindowTool::stop_tool()
153 tool_gui->lock_window("CWindowTool::stop_tool");
154 tool_gui->set_done(0);
155 tool_gui->unlock_window();
159 void CWindowTool::show_tool()
161 if(tool_gui && mwindow->edl->session->tool_window)
163 tool_gui->lock_window("CWindowTool::show_tool");
164 tool_gui->show_window();
165 tool_gui->unlock_window();
169 void CWindowTool::hide_tool()
171 if(tool_gui && mwindow->edl->session->tool_window)
173 tool_gui->lock_window("CWindowTool::show_tool");
174 tool_gui->hide_window();
175 tool_gui->unlock_window();
180 void CWindowTool::run()
184 input_lock->lock("CWindowTool::run");
187 tool_gui->run_window();
188 tool_gui_lock->lock("CWindowTool::run");
191 tool_gui_lock->unlock();
193 output_lock->unlock();
197 void CWindowTool::update_show_window()
201 tool_gui->lock_window("CWindowTool::update_show_window");
203 if(mwindow->edl->session->tool_window)
206 tool_gui->show_window();
209 tool_gui->hide_window();
212 tool_gui->unlock_window();
216 void CWindowTool::raise_window()
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");
228 void CWindowTool::update_values()
230 tool_gui_lock->lock("CWindowTool::update_values");
233 tool_gui->lock_window("CWindowTool::update_values");
236 tool_gui->unlock_window();
238 tool_gui_lock->unlock();
247 CWindowToolGUI::CWindowToolGUI(MWindow *mwindow,
253 mwindow->session->ctool_x,
254 mwindow->session->ctool_y,
263 this->mwindow = mwindow;
264 this->thread = thread;
265 current_operation = 0;
268 CWindowToolGUI::~CWindowToolGUI()
272 int CWindowToolGUI::close_event()
276 mwindow->edl->session->tool_window = 0;
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();
286 lock_window("CWindowToolGUI::close_event");
290 int CWindowToolGUI::keypress_event()
292 if(get_keypress() == 'w' || get_keypress() == 'W')
293 return close_event();
297 int CWindowToolGUI::translation_event()
299 mwindow->session->ctool_x = get_x();
300 mwindow->session->ctool_y = get_y();
309 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value, int log_increment = 0)
310 : BC_TumbleTextBox(gui, (float)value, (float)-65536, (float)65536, x, y, 100)
313 set_log_floatincrement(log_increment);
316 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
317 : BC_TumbleTextBox(gui, (int64_t)value, (int64_t)-65536, (int64_t)65536, x, y, 100)
321 int CWindowCoord::handle_event()
323 gui->event_caller = this;
329 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
330 : BC_GenericButton(x, y, _("Do it"))
332 this->mwindow = mwindow;
335 int CWindowCropOK::handle_event()
337 mwindow->crop_video();
342 int CWindowCropOK::keypress_event()
344 if(get_keypress() == 0xd)
358 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
359 : CWindowToolGUI(mwindow,
361 _(PROGRAM_NAME ": Crop"),
368 CWindowCropGUI::~CWindowCropGUI()
372 void CWindowCropGUI::create_objects()
377 lock_window("CWindowCropGUI::create_objects");
379 int pad = MAX(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1),
380 BC_Title::calculate_h(this, "X")) + 5;
381 add_subwindow(title = new BC_Title(x, y, "X1:"));
382 column1 = MAX(column1, title->get_w());
384 add_subwindow(title = new BC_Title(x, y, _("W:")));
385 column1 = MAX(column1, title->get_w());
387 add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
391 x1 = new CWindowCoord(thread->tool_gui, x, y,
392 mwindow->edl->session->crop_x1);
393 x1->create_objects();
395 width = new CWindowCoord(thread->tool_gui, x, y,
396 mwindow->edl->session->crop_x2 - mwindow->edl->session->crop_x1);
397 width->create_objects();
400 x += x1->get_w() + 10;
403 add_subwindow(title = new BC_Title(x, y, "Y1:"));
404 column2 = MAX(column2, title->get_w());
406 add_subwindow(title = new BC_Title(x, y, _("H:")));
407 column2 = MAX(column2, title->get_w());
412 y1 = new CWindowCoord(thread->tool_gui, x, y,
413 mwindow->edl->session->crop_y1);
414 y1->create_objects();
416 height = new CWindowCoord(thread->tool_gui, x, y,
417 mwindow->edl->session->crop_y2 - mwindow->edl->session->crop_y1);
418 height->create_objects();
422 void CWindowCropGUI::handle_event()
425 new_x1 = atol(x1->get_text());
426 new_y1 = atol(y1->get_text());
427 if(new_x1 != mwindow->edl->session->crop_x1)
429 mwindow->edl->session->crop_x2 = new_x1 +
430 mwindow->edl->session->crop_x2 -
431 mwindow->edl->session->crop_x1;
432 mwindow->edl->session->crop_x1 = new_x1;
434 if(new_y1 != mwindow->edl->session->crop_y1)
436 mwindow->edl->session->crop_y2 = new_y1 +
437 mwindow->edl->session->crop_y2 -
438 mwindow->edl->session->crop_y1;
439 mwindow->edl->session->crop_y1 = atol(y1->get_text());
441 mwindow->edl->session->crop_x2 = atol(width->get_text()) +
442 mwindow->edl->session->crop_x1;
443 mwindow->edl->session->crop_y2 = atol(height->get_text()) +
444 mwindow->edl->session->crop_y1;
446 mwindow->cwindow->gui->lock_window("CWindowCropGUI::handle_event");
447 mwindow->cwindow->gui->canvas->draw_refresh();
448 mwindow->cwindow->gui->unlock_window();
451 void CWindowCropGUI::update()
453 x1->update((int64_t)mwindow->edl->session->crop_x1);
454 y1->update((int64_t)mwindow->edl->session->crop_y1);
455 width->update((int64_t)mwindow->edl->session->crop_x2 -
456 mwindow->edl->session->crop_x1);
457 height->update((int64_t)mwindow->edl->session->crop_y2 -
458 mwindow->edl->session->crop_y1);
462 CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
463 : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 290)
467 CWindowEyedropGUI::~CWindowEyedropGUI()
471 void CWindowEyedropGUI::create_objects()
473 int margin = mwindow->theme->widget_border;
476 int x2 = 70, x3 = x2 + 60;
477 lock_window("CWindowEyedropGUI::create_objects");
478 BC_Title *title0, *title1, *title2, *title3, *title4, *title5, *title6, *title7;
479 add_subwindow(title0 = new BC_Title(x, y,_("X,Y:")));
480 y += title0->get_h() + margin;
481 add_subwindow(title7 = new BC_Title(x, y, _("Radius:")));
482 y += BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1) + margin;
484 add_subwindow(title1 = new BC_Title(x, y, _("Red:")));
485 y += title1->get_h() + margin;
486 add_subwindow(title2 = new BC_Title(x, y, _("Green:")));
487 y += title2->get_h() + margin;
488 add_subwindow(title3 = new BC_Title(x, y, _("Blue:")));
489 y += title3->get_h() + margin;
491 add_subwindow(title4 = new BC_Title(x, y, "Y:"));
492 y += title4->get_h() + margin;
493 add_subwindow(title5 = new BC_Title(x, y, "U:"));
494 y += title5->get_h() + margin;
495 add_subwindow(title6 = new BC_Title(x, y, "V:"));
497 add_subwindow(current = new BC_Title(x2, title0->get_y(), ""));
499 radius = new CWindowCoord(this, x2, title7->get_y(),
500 mwindow->edl->session->eyedrop_radius);
501 radius->create_objects();
502 radius->set_boundaries((int64_t)0, (int64_t)255);
504 add_subwindow(red = new BC_Title(x2, title1->get_y(), "0"));
505 add_subwindow(green = new BC_Title(x2, title2->get_y(), "0"));
506 add_subwindow(blue = new BC_Title(x2, title3->get_y(), "0"));
507 add_subwindow(rgb_hex = new BC_Title(x3, red->get_y(), "#000000"));
509 add_subwindow(this->y = new BC_Title(x2, title4->get_y(), "0"));
510 add_subwindow(this->u = new BC_Title(x2, title5->get_y(), "0"));
511 add_subwindow(this->v = new BC_Title(x2, title6->get_y(), "0"));
512 add_subwindow(yuv_hex = new BC_Title(x3, this->y->get_y(), "#000000"));
514 y = title6->get_y() + this->v->get_h() + 2*margin;
515 add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
516 y += sample->get_h() + margin;
517 add_subwindow(use_max = new CWindowEyedropCheckBox(mwindow, this, x, y));
522 void CWindowEyedropGUI::update()
524 char string[BCTEXTLEN];
525 sprintf(string, "%d, %d",
526 thread->gui->eyedrop_x,
527 thread->gui->eyedrop_y);
528 current->update(string);
530 radius->update((int64_t)mwindow->edl->session->eyedrop_radius);
532 LocalSession *local_session = mwindow->edl->local_session;
533 int use_max = local_session->use_max;
534 float r = use_max ? local_session->red_max : local_session->red;
535 float g = use_max ? local_session->green_max : local_session->green;
536 float b = use_max ? local_session->blue_max : local_session->blue;
537 this->red->update(r);
538 this->green->update(g);
539 this->blue->update(b);
541 int rx = 255*r + 0.5; bclamp(rx,0,255);
542 int gx = 255*g + 0.5; bclamp(gx,0,255);
543 int bx = 255*b + 0.5; bclamp(bx,0,255);
544 char rgb_text[BCSTRLEN];
545 sprintf(rgb_text, "#%02x%02x%02x", rx, gx, bx);
546 rgb_hex->update(rgb_text);
549 YUV::rgb_to_yuv_f(r, g, b, y, u, v);
551 this->u->update(u); u += 0.5;
552 this->v->update(v); v += 0.5;
554 int yx = 255*y + 0.5; bclamp(yx,0,255);
555 int ux = 255*u + 0.5; bclamp(ux,0,255);
556 int vx = 255*v + 0.5; bclamp(vx,0,255);
557 char yuv_text[BCSTRLEN];
558 sprintf(yuv_text, "#%02x%02x%02x", yx, ux, vx);
559 yuv_hex->update(yuv_text);
561 int rgb = (rx << 16) | (gx << 8) | (bx << 0);
562 sample->set_color(rgb);
563 sample->draw_box(0, 0, sample->get_w(), sample->get_h());
564 sample->set_color(BLACK);
565 sample->draw_rectangle(0, 0, sample->get_w(), sample->get_h());
569 void CWindowEyedropGUI::handle_event()
571 int new_radius = atoi(radius->get_text());
572 if(new_radius != mwindow->edl->session->eyedrop_radius)
574 CWindowGUI *gui = mwindow->cwindow->gui;
575 if(gui->eyedrop_visible)
577 gui->lock_window("CWindowEyedropGUI::handle_event");
580 gui->canvas->do_eyedrop(rerender, 0, 1);
583 mwindow->edl->session->eyedrop_radius = new_radius;
585 if(gui->eyedrop_visible)
589 gui->canvas->do_eyedrop(rerender, 0, 1);
590 gui->unlock_window();
597 /* Buttons to control Keyframe-Curve-Mode for Projector or Camera */
599 // Configuration for all possible Keyframe Curve Mode toggles
601 FloatAuto::t_mode mode;
607 const _CVD Camera_Crv_Smooth =
611 N_("\"smooth\" Curve on current Camera Keyframes")
613 const _CVD Camera_Crv_Linear =
617 N_("\"linear\" Curve on current Camera Keyframes")
619 const _CVD Projector_Crv_Smooth =
623 N_("\"smooth\" Curve on current Projector Keyframes")
625 const _CVD Projector_Crv_Linear =
629 N_("\"linear\" Curve on current Projector Keyframes")
632 // Implementation Class für Keyframe Curve Mode buttons
634 // This button reflects the state of the "current" keyframe
635 // (the nearest keyframe on the left) for all three automation
636 // lines together. Clicking on this button (re)sets the curve
637 // mode for the three "current" keyframes simultanously, but
638 // never creates a new keyframe.
640 class CWindowCurveToggle : public BC_Toggle
643 CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
644 void check_toggle_state(FloatAuto *x, FloatAuto *y, FloatAuto *z);
653 CWindowCurveToggle::CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
654 : BC_Toggle(x, y, mwindow->theme->get_image_set(mode.icon_id), false),
658 this->mwindow = mwindow;
659 set_tooltip(_(cfg.tooltip));
662 void CWindowCurveToggle::check_toggle_state(FloatAuto *x, FloatAuto *y, FloatAuto *z)
664 // the toggle state is only set to ON if all
665 // three automation lines have the same curve mode.
666 // For mixed states the toggle stays off.
667 set_value( x->curve_mode == this->cfg.mode &&
668 y->curve_mode == this->cfg.mode &&
669 z->curve_mode == this->cfg.mode
670 ,true // redraw to show new state
674 int CWindowCurveToggle::handle_event()
676 FloatAuto *x=0, *y=0, *z=0;
677 Track *track = mwindow->cwindow->calculate_affected_track();
680 { mwindow->cwindow->calculate_affected_autos(&x, &y, &z,
681 track, cfg.use_camera, 0,0,0); // don't create new keyframe
683 if(x) x->change_curve_mode(cfg.mode);
684 if(y) y->change_curve_mode(cfg.mode);
685 if(z) z->change_curve_mode(cfg.mode);
688 gui->update_preview();
695 CWindowEyedropCheckBox::CWindowEyedropCheckBox(MWindow *mwindow,
696 CWindowEyedropGUI *gui, int x, int y)
697 : BC_CheckBox(x, y, mwindow->edl->local_session->use_max, _("Use maximum"))
699 this->mwindow = mwindow;
703 int CWindowEyedropCheckBox::handle_event()
705 mwindow->edl->local_session->use_max = get_value();
712 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
713 : CWindowToolGUI(mwindow,
715 _(PROGRAM_NAME ": Camera"),
720 CWindowCameraGUI::~CWindowCameraGUI()
724 void CWindowCameraGUI::create_objects()
726 int x = 10, y = 10, x1;
727 Track *track = mwindow->cwindow->calculate_affected_track();
728 FloatAuto *x_auto = 0;
729 FloatAuto *y_auto = 0;
730 FloatAuto *z_auto = 0;
734 lock_window("CWindowCameraGUI::create_objects");
737 mwindow->cwindow->calculate_affected_autos(&x_auto,
738 &y_auto, &z_auto, track, 1, 0, 0, 0);
741 add_subwindow(title = new BC_Title(x, y, "X:"));
743 this->x = new CWindowCoord(this, x, y,
744 x_auto ? x_auto->get_value() : (float)0);
745 this->x->create_objects();
750 add_subwindow(title = new BC_Title(x, y, "Y:"));
752 this->y = new CWindowCoord(this, x, y,
753 y_auto ? y_auto->get_value() : (float)0);
754 this->y->create_objects();
757 add_subwindow(title = new BC_Title(x, y, "Z:"));
759 this->z = new CWindowCoord(this, x, y,
760 z_auto ? z_auto->get_value() : (float)1);
761 this->z->create_objects();
762 this->z->set_increment(0.01);
766 add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
767 x1 += button->get_w();
768 add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
769 x1 += button->get_w();
770 add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
772 y += button->get_h();
774 add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
775 x1 += button->get_w();
776 add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
777 x1 += button->get_w();
778 add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
779 // additional Buttons to control the curve mode of the "current" keyframe
780 x1 += button->get_w() + 15;
781 add_subwindow(this->t_smooth = new CWindowCurveToggle(Camera_Crv_Smooth, mwindow, this, x1, y));
782 x1 += button->get_w();
783 add_subwindow(this->t_linear = new CWindowCurveToggle(Camera_Crv_Linear, mwindow, this, x1, y));
785 // fill in current auto keyframe values, set toggle states.
790 void CWindowCameraGUI::update_preview()
792 mwindow->gui->lock_window("CWindowCameraGUI::update_preview");
793 mwindow->restart_brender();
794 mwindow->gui->draw_overlays(1);
795 mwindow->sync_parameters(CHANGE_PARAMS);
796 mwindow->gui->unlock_window();
797 mwindow->cwindow->refresh_frame(CHANGE_NONE);
798 mwindow->cwindow->gui->lock_window("CWindowCameraGUI::update_preview");
799 mwindow->cwindow->gui->canvas->draw_refresh();
800 mwindow->cwindow->gui->unlock_window();
804 void CWindowCameraGUI::handle_event()
806 FloatAuto *x_auto = 0;
807 FloatAuto *y_auto = 0;
808 FloatAuto *z_auto = 0;
809 Track *track = mwindow->cwindow->calculate_affected_track();
812 mwindow->undo->update_undo_before(_("camera"), this);
813 if(event_caller == x)
815 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
816 track->automation->autos[AUTOMATION_CAMERA_X],
820 x_auto->set_value(atof(x->get_text()));
826 if(event_caller == y)
828 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
829 track->automation->autos[AUTOMATION_CAMERA_Y],
833 y_auto->set_value(atof(y->get_text()));
839 if(event_caller == z)
841 z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
842 track->automation->autos[AUTOMATION_CAMERA_Z],
846 float zoom = atof(z->get_text());
847 if(zoom > 100.) zoom = 100.;
849 if(zoom < 0.01) zoom = 0.01;
850 // Doesn't allow user to enter from scratch
851 // if(zoom != atof(z->get_text()))
854 z_auto->set_value(zoom);
855 mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
856 mwindow->gui->draw_overlays(1);
857 mwindow->gui->unlock_window();
863 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
867 void CWindowCameraGUI::update()
869 FloatAuto *x_auto = 0;
870 FloatAuto *y_auto = 0;
871 FloatAuto *z_auto = 0;
872 Track *track = mwindow->cwindow->calculate_affected_track();
876 mwindow->cwindow->calculate_affected_autos(&x_auto,
887 x->update(x_auto->get_value());
889 y->update(y_auto->get_value());
891 float value = z_auto->get_value();
893 thread->gui->composite_panel->cpanel_zoom->update(value);
896 if( x_auto && y_auto && z_auto )
898 t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
899 t_linear->check_toggle_state(x_auto, y_auto, z_auto);
906 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
907 : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
910 this->mwindow = mwindow;
911 set_tooltip(_("Left justify"));
913 int CWindowCameraLeft::handle_event()
915 FloatAuto *x_auto = 0;
916 FloatAuto *z_auto = 0;
917 Track *track = mwindow->cwindow->calculate_affected_track();
920 mwindow->cwindow->calculate_affected_autos(&x_auto,
933 track->get_source_dimensions(
934 mwindow->edl->local_session->get_selectionstart(1),
940 mwindow->undo->update_undo_before(_("camera"), 0);
942 (double)track->track_w / z_auto->get_value() / 2 -
944 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
946 gui->update_preview();
954 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
955 : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
958 this->mwindow = mwindow;
959 set_tooltip(_("Center horizontal"));
961 int CWindowCameraCenter::handle_event()
963 FloatAuto *x_auto = 0;
964 Track *track = mwindow->cwindow->calculate_affected_track();
966 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
967 track->automation->autos[AUTOMATION_CAMERA_X],
972 mwindow->undo->update_undo_before(_("camera"), 0);
973 x_auto->set_value(0);
975 gui->update_preview();
976 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
983 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
984 : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
987 this->mwindow = mwindow;
988 set_tooltip(_("Right justify"));
990 int CWindowCameraRight::handle_event()
992 FloatAuto *x_auto = 0;
993 FloatAuto *z_auto = 0;
994 Track *track = mwindow->cwindow->calculate_affected_track();
997 mwindow->cwindow->calculate_affected_autos(&x_auto,
1007 if(x_auto && z_auto)
1010 track->get_source_dimensions(
1011 mwindow->edl->local_session->get_selectionstart(1),
1017 mwindow->undo->update_undo_before(_("camera"), 0);
1018 x_auto->set_value( -((double)track->track_w / z_auto->get_value() / 2 -
1021 gui->update_preview();
1022 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1030 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1031 : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1034 this->mwindow = mwindow;
1035 set_tooltip(_("Top justify"));
1037 int CWindowCameraTop::handle_event()
1039 FloatAuto *y_auto = 0;
1040 FloatAuto *z_auto = 0;
1041 Track *track = mwindow->cwindow->calculate_affected_track();
1044 mwindow->cwindow->calculate_affected_autos(0,
1054 if(y_auto && z_auto)
1057 track->get_source_dimensions(
1058 mwindow->edl->local_session->get_selectionstart(1),
1064 mwindow->undo->update_undo_before(_("camera"), 0);
1065 y_auto->set_value((double)track->track_h / z_auto->get_value() / 2 -
1068 gui->update_preview();
1069 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1077 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1078 : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1081 this->mwindow = mwindow;
1082 set_tooltip(_("Center vertical"));
1084 int CWindowCameraMiddle::handle_event()
1086 FloatAuto *y_auto = 0;
1087 Track *track = mwindow->cwindow->calculate_affected_track();
1089 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1090 track->automation->autos[AUTOMATION_CAMERA_Y], 1);
1094 mwindow->undo->update_undo_before(_("camera"), 0);
1095 y_auto->set_value(0);
1097 gui->update_preview();
1098 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1105 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1106 : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1109 this->mwindow = mwindow;
1110 set_tooltip(_("Bottom justify"));
1112 int CWindowCameraBottom::handle_event()
1114 FloatAuto *y_auto = 0;
1115 FloatAuto *z_auto = 0;
1116 Track *track = mwindow->cwindow->calculate_affected_track();
1119 mwindow->cwindow->calculate_affected_autos(0,
1129 if(y_auto && z_auto)
1132 track->get_source_dimensions(
1133 mwindow->edl->local_session->get_selectionstart(1),
1139 mwindow->undo->update_undo_before(_("camera"), 0);
1140 y_auto->set_value(-((double)track->track_h / z_auto->get_value() / 2 -
1143 gui->update_preview();
1144 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1152 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
1153 : CWindowToolGUI(mwindow,
1155 _(PROGRAM_NAME ": Projector"),
1160 CWindowProjectorGUI::~CWindowProjectorGUI()
1163 void CWindowProjectorGUI::create_objects()
1165 int x = 10, y = 10, x1;
1166 Track *track = mwindow->cwindow->calculate_affected_track();
1167 FloatAuto *x_auto = 0;
1168 FloatAuto *y_auto = 0;
1169 FloatAuto *z_auto = 0;
1173 lock_window("CWindowProjectorGUI::create_objects");
1176 mwindow->cwindow->calculate_affected_autos(&x_auto,
1186 add_subwindow(title = new BC_Title(x, y, "X:"));
1187 x += title->get_w();
1188 this->x = new CWindowCoord(this, x, y,
1189 x_auto ? x_auto->get_value() : (float)0);
1190 this->x->create_objects();
1193 add_subwindow(title = new BC_Title(x, y, "Y:"));
1194 x += title->get_w();
1195 this->y = new CWindowCoord(this, x, y,
1196 y_auto ? y_auto->get_value() : (float)0);
1197 this->y->create_objects();
1200 add_subwindow(title = new BC_Title(x, y, "Z:"));
1201 x += title->get_w();
1202 this->z = new CWindowCoord(this, x, y,
1203 z_auto ? z_auto->get_value() : (float)1);
1204 this->z->create_objects();
1205 this->z->set_increment(0.01);
1209 add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
1210 x1 += button->get_w();
1211 add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
1212 x1 += button->get_w();
1213 add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
1215 y += button->get_h();
1217 add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
1218 x1 += button->get_w();
1219 add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
1220 x1 += button->get_w();
1221 add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
1223 // additional Buttons to control the curve mode of the "current" keyframe
1224 x1 += button->get_w() + 15;
1225 add_subwindow(this->t_smooth = new CWindowCurveToggle(Projector_Crv_Smooth, mwindow, this, x1, y));
1226 x1 += button->get_w();
1227 add_subwindow(this->t_linear = new CWindowCurveToggle(Projector_Crv_Linear, mwindow, this, x1, y));
1229 // fill in current auto keyframe values, set toggle states.
1234 void CWindowProjectorGUI::update_preview()
1236 mwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
1237 mwindow->restart_brender();
1238 mwindow->sync_parameters(CHANGE_PARAMS);
1239 mwindow->gui->draw_overlays(1);
1240 mwindow->gui->unlock_window();
1241 mwindow->cwindow->refresh_frame(CHANGE_NONE);
1242 mwindow->cwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
1243 mwindow->cwindow->gui->canvas->draw_refresh();
1244 mwindow->cwindow->gui->unlock_window();
1247 void CWindowProjectorGUI::handle_event()
1249 FloatAuto *x_auto = 0;
1250 FloatAuto *y_auto = 0;
1251 FloatAuto *z_auto = 0;
1252 Track *track = mwindow->cwindow->calculate_affected_track();
1256 mwindow->undo->update_undo_before(_("projector"), this);
1257 if(event_caller == x)
1259 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1260 track->automation->autos[AUTOMATION_PROJECTOR_X],
1264 x_auto->set_value(atof(x->get_text()));
1270 if(event_caller == y)
1272 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1273 track->automation->autos[AUTOMATION_PROJECTOR_Y],
1277 y_auto->set_value(atof(y->get_text()));
1283 if(event_caller == z)
1285 z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1286 track->automation->autos[AUTOMATION_PROJECTOR_Z],
1290 float zoom = atof(z->get_text());
1291 if(zoom > 100.) zoom = 100.;
1292 else if(zoom < 0.01) zoom = 0.01;
1293 // if (zoom != atof(z->get_text()))
1295 z_auto->set_value(zoom);
1297 mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
1298 mwindow->gui->draw_overlays(1);
1299 mwindow->gui->unlock_window();
1305 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1309 void CWindowProjectorGUI::update()
1311 FloatAuto *x_auto = 0;
1312 FloatAuto *y_auto = 0;
1313 FloatAuto *z_auto = 0;
1314 Track *track = mwindow->cwindow->calculate_affected_track();
1318 mwindow->cwindow->calculate_affected_autos(&x_auto,
1329 x->update(x_auto->get_value());
1331 y->update(y_auto->get_value());
1333 float value = z_auto->get_value();
1335 thread->gui->composite_panel->cpanel_zoom->update(value);
1338 if( x_auto && y_auto && z_auto )
1340 t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
1341 t_linear->check_toggle_state(x_auto, y_auto, z_auto);
1345 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1346 : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
1349 this->mwindow = mwindow;
1350 set_tooltip(_("Left justify"));
1352 int CWindowProjectorLeft::handle_event()
1354 FloatAuto *x_auto = 0;
1355 FloatAuto *z_auto = 0;
1356 Track *track = mwindow->cwindow->calculate_affected_track();
1359 mwindow->cwindow->calculate_affected_autos(&x_auto,
1368 if(x_auto && z_auto)
1370 mwindow->undo->update_undo_before(_("projector"), 0);
1371 x_auto->set_value( (double)track->track_w * z_auto->get_value() / 2 -
1372 (double)mwindow->edl->session->output_w / 2 );
1374 gui->update_preview();
1375 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1382 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1383 : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
1386 this->mwindow = mwindow;
1387 set_tooltip(_("Center horizontal"));
1389 int CWindowProjectorCenter::handle_event()
1391 FloatAuto *x_auto = 0;
1392 Track *track = mwindow->cwindow->calculate_affected_track();
1394 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1395 track->automation->autos[AUTOMATION_PROJECTOR_X],
1400 mwindow->undo->update_undo_before(_("projector"), 0);
1401 x_auto->set_value(0);
1403 gui->update_preview();
1404 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1411 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1412 : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
1415 this->mwindow = mwindow;
1416 set_tooltip(_("Right justify"));
1418 int CWindowProjectorRight::handle_event()
1420 FloatAuto *x_auto = 0;
1421 FloatAuto *z_auto = 0;
1422 Track *track = mwindow->cwindow->calculate_affected_track();
1425 mwindow->cwindow->calculate_affected_autos(&x_auto,
1435 if(x_auto && z_auto)
1437 mwindow->undo->update_undo_before(_("projector"), 0);
1438 x_auto->set_value( -((double)track->track_w * z_auto->get_value() / 2 -
1439 (double)mwindow->edl->session->output_w / 2));
1441 gui->update_preview();
1442 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1449 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1450 : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1453 this->mwindow = mwindow;
1454 set_tooltip(_("Top justify"));
1456 int CWindowProjectorTop::handle_event()
1458 FloatAuto *y_auto = 0;
1459 FloatAuto *z_auto = 0;
1460 Track *track = mwindow->cwindow->calculate_affected_track();
1463 mwindow->cwindow->calculate_affected_autos(0,
1473 if(y_auto && z_auto)
1475 mwindow->undo->update_undo_before(_("projector"), 0);
1476 y_auto->set_value( (double)track->track_h * z_auto->get_value() / 2 -
1477 (double)mwindow->edl->session->output_h / 2 );
1479 gui->update_preview();
1480 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1487 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1488 : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1491 this->mwindow = mwindow;
1492 set_tooltip(_("Center vertical"));
1494 int CWindowProjectorMiddle::handle_event()
1496 FloatAuto *y_auto = 0;
1497 Track *track = mwindow->cwindow->calculate_affected_track();
1499 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1500 track->automation->autos[AUTOMATION_PROJECTOR_Y], 1);
1504 mwindow->undo->update_undo_before(_("projector"), 0);
1505 y_auto->set_value(0);
1507 gui->update_preview();
1508 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1515 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1516 : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1519 this->mwindow = mwindow;
1520 set_tooltip(_("Bottom justify"));
1522 int CWindowProjectorBottom::handle_event()
1524 FloatAuto *y_auto = 0;
1525 FloatAuto *z_auto = 0;
1526 Track *track = mwindow->cwindow->calculate_affected_track();
1529 mwindow->cwindow->calculate_affected_autos(0,
1539 if(y_auto && z_auto)
1541 mwindow->undo->update_undo_before(_("projector"), 0);
1542 y_auto->set_value( -((double)track->track_h * z_auto->get_value() / 2 -
1543 (double)mwindow->edl->session->output_h / 2));
1545 gui->update_preview();
1546 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1553 CWindowMaskMode::CWindowMaskMode(MWindow *mwindow,
1554 CWindowToolGUI *gui, int x, int y, const char *text)
1555 : BC_PopupMenu(x, y, 220, text, 1)
1557 this->mwindow = mwindow;
1561 void CWindowMaskMode::create_objects()
1563 add_item(new BC_MenuItem(mode_to_text(MASK_MULTIPLY_ALPHA)));
1564 add_item(new BC_MenuItem(mode_to_text(MASK_SUBTRACT_ALPHA)));
1567 char* CWindowMaskMode::mode_to_text(int mode)
1571 case MASK_MULTIPLY_ALPHA:
1572 return _("Multiply alpha");
1575 case MASK_SUBTRACT_ALPHA:
1576 return _("Subtract alpha");
1580 return _("Subtract alpha");
1583 int CWindowMaskMode::text_to_mode(char *text)
1585 if(!strcasecmp(text, _("Multiply alpha")))
1586 return MASK_MULTIPLY_ALPHA;
1588 if(!strcasecmp(text, _("Subtract alpha")))
1589 return MASK_SUBTRACT_ALPHA;
1591 return MASK_SUBTRACT_ALPHA;
1594 int CWindowMaskMode::handle_event()
1601 // Get existing keyframe
1602 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1605 mwindow->undo->update_undo_before(_("mask mode"), 0);
1606 #ifdef USE_KEYFRAME_SPANNING
1607 // Create temp keyframe
1608 MaskAuto temp_keyframe(mwindow->edl, autos);
1609 temp_keyframe.copy_data(keyframe);
1611 temp_keyframe.mode = text_to_mode(get_text());
1612 // Commit change to span of keyframes
1613 autos->update_parameter(&temp_keyframe);
1615 ((MaskAuto*)autos->default_auto)->mode =
1616 text_to_mode(get_text());
1618 mwindow->undo->update_undo_after(_("mask mode"), LOAD_AUTOMATION);
1621 //printf("CWindowMaskMode::handle_event 1\n");
1622 gui->update_preview();
1633 CWindowMaskDelete::CWindowMaskDelete(MWindow *mwindow,
1634 CWindowToolGUI *gui,
1637 : BC_GenericButton(x, y, _("Delete"))
1639 this->mwindow = mwindow;
1643 int CWindowMaskDelete::handle_event()
1650 int total_points = 0;
1652 // Get existing keyframe
1653 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1657 mwindow->undo->update_undo_before(_("mask delete"), 0);
1659 #ifdef USE_KEYFRAME_SPANNING
1660 // Create temp keyframe
1661 MaskAuto temp_keyframe(mwindow->edl, autos);
1662 temp_keyframe.copy_data(keyframe);
1664 SubMask *submask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
1665 for(int i = mwindow->cwindow->gui->affected_point;
1666 i < submask->points.total - 1;
1669 *submask->points.values[i] = *submask->points.values[i + 1];
1672 if(submask->points.total)
1674 submask->points.remove_object(
1675 submask->points.values[submask->points.total - 1]);
1677 total_points = submask->points.total;
1679 // Commit change to span of keyframes
1680 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->update_parameter(&temp_keyframe);
1682 for(MaskAuto *current = (MaskAuto*)autos->default_auto;
1685 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1687 for(int i = mwindow->cwindow->gui->affected_point;
1688 i < submask->points.total - 1;
1691 *submask->points.values[i] = *submask->points.values[i + 1];
1694 if(submask->points.total)
1696 submask->points.remove_object(
1697 submask->points.values[submask->points.total - 1]);
1699 total_points = submask->points.total;
1701 if(current == (MaskAuto*)autos->default_auto)
1702 current = (MaskAuto*)autos->first;
1704 current = (MaskAuto*)NEXT;
1707 if( mwindow->cwindow->gui->affected_point >= total_points )
1708 mwindow->cwindow->gui->affected_point =
1709 total_points > 0 ? total_points-1 : 0;
1712 gui->update_preview();
1713 mwindow->undo->update_undo_after(_("mask delete"), LOAD_AUTOMATION);
1720 int CWindowMaskDelete::keypress_event()
1722 if(get_keypress() == BACKSPACE ||
1723 get_keypress() == DELETE)
1724 return handle_event();
1729 // CWindowMaskCycleNext::CWindowMaskCycleNext(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1730 // : BC_GenericButton(x, y, _("Cycle next"))
1732 // this->mwindow = mwindow;
1735 // int CWindowMaskCycleNext::handle_event()
1737 // MaskAuto *keyframe;
1738 // MaskAutos *autos;
1740 // MaskPoint *point;
1742 // ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1746 // // Should apply to all keyframes
1747 // if(keyframe && mask->points.total)
1749 // temp = mask->points.values[0];
1751 // for(int i = 0; i < mask->points.total - 1; i++)
1753 // mask->points.values[i] = mask->points.values[i + 1];
1755 // mask->points.values[mask->points.total - 1] = temp;
1757 // mwindow->cwindow->gui->affected_point--;
1758 // if(mwindow->cwindow->gui->affected_point < 0)
1759 // mwindow->cwindow->gui->affected_point = mask->points.total - 1;
1762 // gui->update_preview();
1768 // CWindowMaskCyclePrev::CWindowMaskCyclePrev(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1769 // : BC_GenericButton(x, y, _("Cycle prev"))
1771 // this->mwindow = mwindow;
1774 // int CWindowMaskCyclePrev::handle_event()
1776 // MaskAuto *keyframe;
1777 // MaskAutos *autos;
1779 // MaskPoint *point;
1781 // ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1783 // // Should apply to all keyframes
1785 // if(keyframe && mask->points.total)
1787 // temp = mask->points.values[mask->points.total - 1];
1789 // for(int i = mask->points.total - 1; i > 0; i--)
1791 // mask->points.values[i] = mask->points.values[i - 1];
1793 // mask->points.values[0] = temp;
1795 // mwindow->cwindow->gui->affected_point++;
1796 // if(mwindow->cwindow->gui->affected_point >= mask->points.total)
1797 // mwindow->cwindow->gui->affected_point = 0;
1800 // gui->update_preview();
1806 CWindowMaskNumber::CWindowMaskNumber(MWindow *mwindow,
1807 CWindowToolGUI *gui,
1810 : BC_TumbleTextBox(gui,
1811 (int64_t)mwindow->edl->session->cwindow_mask,
1813 (int64_t)SUBMASKS - 1,
1818 this->mwindow = mwindow;
1822 CWindowMaskNumber::~CWindowMaskNumber()
1826 int CWindowMaskNumber::handle_event()
1828 mwindow->edl->session->cwindow_mask = atol(get_text());
1830 gui->update_preview();
1835 CWindowMaskAffectedPoint::CWindowMaskAffectedPoint(MWindow *mwindow,
1836 CWindowToolGUI *gui, int x, int y)
1837 : BC_TumbleTextBox(gui,
1838 (int64_t)mwindow->cwindow->gui->affected_point,
1839 (int64_t)0, INT64_MAX, x, y, 100)
1841 this->mwindow = mwindow;
1845 CWindowMaskAffectedPoint::~CWindowMaskAffectedPoint()
1849 int CWindowMaskAffectedPoint::handle_event()
1851 int total_points = 0;
1852 int affected_point = atol(get_text());
1853 Track *track = mwindow->cwindow->calculate_affected_track();
1855 MaskAutos *autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
1856 MaskAuto *keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(autos, 0);
1858 SubMask *mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
1859 total_points = mask->points.size();
1862 int active_point = affected_point;
1863 if( affected_point >= total_points )
1864 affected_point = total_points - 1;
1865 else if( affected_point < 0 )
1867 if( active_point != affected_point )
1868 update((int64_t)affected_point);
1869 mwindow->cwindow->gui->affected_point = affected_point;
1871 gui->update_preview();
1879 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1880 : BC_TumbleTextBox(gui,
1888 this->mwindow = mwindow;
1891 CWindowMaskFeather::~CWindowMaskFeather()
1894 int CWindowMaskFeather::handle_event()
1901 #ifdef USE_KEYFRAME_SPANNING
1907 mwindow->undo->update_undo_before(_("mask feather"), this);
1909 // Get existing keyframe
1910 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe,
1911 mask, point, create_it);
1915 #ifdef USE_KEYFRAME_SPANNING
1916 // Create temp keyframe
1917 MaskAuto temp_keyframe(mwindow->edl, autos);
1918 temp_keyframe.copy_data(keyframe);
1920 temp_keyframe.feather = atof(get_text());
1921 // Commit change to span of keyframes
1922 autos->update_parameter(&temp_keyframe);
1924 keyframe->feather = atof(get_text());
1927 gui->update_preview();
1930 mwindow->undo->update_undo_after(_("mask feather"), LOAD_AUTOMATION);
1935 CWindowMaskValue::CWindowMaskValue(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1945 this->mwindow = mwindow;
1949 CWindowMaskValue::~CWindowMaskValue()
1953 int CWindowMaskValue::handle_event()
1960 #ifdef USE_KEYFRAME_SPANNING
1966 mwindow->undo->update_undo_before(_("mask value"), this);
1967 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe,
1968 mask, point, create_it);
1972 #ifdef USE_KEYFRAME_SPANNING
1973 // Create temp keyframe
1974 MaskAuto temp_keyframe(mwindow->edl, autos);
1975 temp_keyframe.copy_data(keyframe);
1977 temp_keyframe.value = get_value();
1978 // Commit change to span of keyframes
1979 autos->update_parameter(&temp_keyframe);
1981 keyframe->value = get_value();
1985 gui->update_preview();
1986 mwindow->undo->update_undo_after(_("mask value"), LOAD_AUTOMATION);
1991 CWindowMaskBeforePlugins::CWindowMaskBeforePlugins(CWindowToolGUI *gui, int x, int y)
1995 _("Apply mask before plugins"))
2000 int CWindowMaskBeforePlugins::handle_event()
2007 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 1);
2010 keyframe->apply_before_plugins = get_value();
2011 gui->update_preview();
2017 CWindowDisableOpenGLMasking::CWindowDisableOpenGLMasking(CWindowToolGUI *gui, int x, int y)
2018 : BC_CheckBox(x, y, 1, _("Disable OpenGL masking"))
2023 int CWindowDisableOpenGLMasking::handle_event()
2030 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 1);
2033 keyframe->disable_opengl_masking = get_value();
2034 gui->update_preview();
2047 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
2048 : CWindowToolGUI(mwindow,
2050 _(PROGRAM_NAME ": Mask"),
2054 this->mwindow = mwindow;
2055 this->thread = thread;
2060 CWindowMaskGUI::~CWindowMaskGUI()
2062 lock_window("CWindowMaskGUI::~CWindowMaskGUI");
2064 delete active_point;
2069 void CWindowMaskGUI::create_objects()
2071 int x = 10, y = 10, margin = mwindow->theme->widget_border;
2072 //MaskAuto *keyframe = 0;
2073 //Track *track = mwindow->cwindow->calculate_affected_track();
2075 // keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], 0);
2077 lock_window("CWindowMaskGUI::create_objects");
2079 add_subwindow(title = new BC_Title(x, y, _("Mode:")));
2080 add_subwindow(mode = new CWindowMaskMode(mwindow,
2081 this, x + title->get_w() + margin, y, ""));
2082 mode->create_objects();
2083 y += mode->get_h() + margin;
2084 add_subwindow(title = new BC_Title(x, y, _("Value:")));
2085 add_subwindow(value = new CWindowMaskValue(mwindow, this, x + title->get_w() + margin, y));
2086 y += value->get_h() + margin;
2087 add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
2088 int x1 = x + delete_point->get_w() + 2*margin;
2089 add_subwindow(title = new BC_Title(x1, y, _("Point:")));
2090 x1 += title->get_w() + margin;
2091 active_point = new CWindowMaskAffectedPoint(mwindow, this, x1, y);
2092 active_point->create_objects();
2093 y += delete_point->get_h() + margin;
2094 add_subwindow(title = new BC_Title(x, y, _("Mask number:")));
2095 number = new CWindowMaskNumber(mwindow,
2096 this, x + title->get_w() + margin, y);
2097 number->create_objects();
2098 y += number->get_h() + margin;
2099 add_subwindow(title = new BC_Title(x, y, _("Feather:")));
2100 feather = new CWindowMaskFeather(mwindow,
2101 this, x + title->get_w() + margin, y);
2102 feather->create_objects();
2103 y += feather->get_h() + margin;
2104 add_subwindow(title = new BC_Title(x, y, "X:"));
2105 x += title->get_w() + margin;
2106 this->x = new CWindowCoord(this, x, y, (float)0.0);
2107 this->x->create_objects();
2108 x += this->x->get_w() + margin;
2109 add_subwindow(title = new BC_Title(x, y, "Y:"));
2110 x += title->get_w() + margin;
2111 this->y = new CWindowCoord(this, x, y, (float)0.0);
2112 this->y->create_objects();
2115 y += this->y->get_h() + margin;
2116 add_subwindow(title = new BC_Title(x, y, _("Press Shift to move an end point")));
2117 y += title->get_h() + margin;
2118 add_subwindow(title = new BC_Title(x, y, _("Press Ctrl to move a control point")));
2119 y += title->get_h() + margin;
2120 add_subwindow(title = new BC_Title(x, y, _("Press Alt to translate the mask")));
2123 add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this, 10, y));
2124 y += this->apply_before_plugins->get_h() + margin;
2125 add_subwindow(this->disable_opengl_masking = new CWindowDisableOpenGLMasking(this, 10, y));
2131 void CWindowMaskGUI::get_keyframe(Track* &track,
2133 MaskAuto* &keyframe,
2141 track = mwindow->cwindow->calculate_affected_track();
2144 autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
2145 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(
2151 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
2158 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2159 mwindow->cwindow->gui->affected_point >= 0)
2161 point = mask->points.values[mwindow->cwindow->gui->affected_point];
2166 void CWindowMaskGUI::update()
2173 //printf("CWindowMaskGUI::update 1\n");
2174 get_keyframe(track, autos, keyframe, mask, point, 0);
2176 double position = mwindow->edl->local_session->get_selectionstart(1);
2177 position = mwindow->edl->align_to_frame(position, 0);
2180 int64_t position_i = track->to_units(position, 0);
2184 x->update(point->x);
2185 y->update(point->y);
2190 feather->update((int64_t)autos->get_feather(position_i, PLAY_FORWARD));
2191 value->update((int64_t)autos->get_value(position_i, PLAY_FORWARD));
2192 apply_before_plugins->update((int64_t)keyframe->apply_before_plugins);
2193 disable_opengl_masking->update((int64_t)keyframe->disable_opengl_masking);
2197 //printf("CWindowMaskGUI::update 1\n");
2198 active_point->update((int64_t)mwindow->cwindow->gui->affected_point);
2199 number->update((int64_t)mwindow->edl->session->cwindow_mask);
2201 //printf("CWindowMaskGUI::update 1\n");
2204 #ifdef USE_KEYFRAME_SPANNING
2206 CWindowMaskMode::mode_to_text(keyframe->mode));
2209 CWindowMaskMode::mode_to_text(((MaskAuto*)autos->default_auto)->mode));
2212 //printf("CWindowMaskGUI::update 2\n");
2215 void CWindowMaskGUI::handle_event()
2222 get_keyframe(track, autos, keyframe, mask, point, 0);
2224 mwindow->undo->update_undo_before(_("mask point"), this);
2228 #ifdef USE_KEYFRAME_SPANNING
2229 // Create temp keyframe
2230 MaskAuto temp_keyframe(mwindow->edl, autos);
2231 temp_keyframe.copy_data(keyframe);
2232 // Get affected point in temp keyframe
2233 mask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
2234 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2235 mwindow->cwindow->gui->affected_point >= 0)
2237 point = mask->points.values[mwindow->cwindow->gui->affected_point];
2242 point->x = atof(x->get_text());
2243 point->y = atof(y->get_text());
2244 // Commit to spanned keyframes
2245 autos->update_parameter(&temp_keyframe);
2248 point->x = atof(x->get_text());
2249 point->y = atof(y->get_text());
2254 mwindow->undo->update_undo_after(_("mask point"), LOAD_AUTOMATION);
2257 void CWindowMaskGUI::update_preview()
2259 mwindow->gui->lock_window("CWindowMaskGUI::update_preview");
2260 mwindow->restart_brender();
2261 mwindow->sync_parameters(CHANGE_PARAMS);
2262 mwindow->gui->draw_overlays(1);
2263 mwindow->gui->unlock_window();
2264 mwindow->cwindow->refresh_frame(CHANGE_NONE);
2265 mwindow->cwindow->gui->lock_window("CWindowMaskGUI::update_preview");
2266 mwindow->cwindow->gui->canvas->draw_refresh();
2267 mwindow->cwindow->gui->unlock_window();
2271 CWindowRulerGUI::CWindowRulerGUI(MWindow *mwindow, CWindowTool *thread)
2272 : CWindowToolGUI(mwindow,
2274 _(PROGRAM_NAME ": Ruler"),
2280 CWindowRulerGUI::~CWindowRulerGUI()
2284 void CWindowRulerGUI::create_objects()
2289 lock_window("CWindowRulerGUI::create_objects");
2290 add_subwindow(title = new BC_Title(x, y, _("Current:")));
2291 add_subwindow(current = new BC_Title(x + title->get_w() + 10, y, ""));
2292 y += title->get_h() + 5;
2294 add_subwindow(title = new BC_Title(x, y, _("Point 1:")));
2295 add_subwindow(point1 = new BC_Title(x + title->get_w() + 10, y, ""));
2296 y += title->get_h() + 5;
2298 add_subwindow(title = new BC_Title(x, y, _("Point 2:")));
2299 add_subwindow(point2 = new BC_Title(x + title->get_w() + 10, y, ""));
2300 y += title->get_h() + 5;
2302 add_subwindow(title = new BC_Title(x, y, _("Distance:")));
2303 add_subwindow(distance = new BC_Title(x + title->get_w() + 10, y, ""));
2304 y += title->get_h() + 5;
2305 add_subwindow(title = new BC_Title(x, y, _("Angle:")));
2306 add_subwindow(angle = new BC_Title(x + title->get_w() + 10, y, ""));
2307 y += title->get_h() + 10;
2308 char string[BCTEXTLEN];
2309 sprintf(string, _("Press Ctrl to lock ruler to the\nnearest 45%c angle."), 0xb0);
2310 add_subwindow(title = new BC_Title(x,
2313 y += title->get_h() + 10;
2314 sprintf(string, _("Press Alt to translate the ruler."));
2315 add_subwindow(title = new BC_Title(x,
2322 void CWindowRulerGUI::update()
2324 double distance_value =
2325 sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) +
2326 SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1));
2327 double angle_value = atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) /
2328 (mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) *
2333 if(EQUIV(distance_value, 0.0))
2343 char string[BCTEXTLEN];
2344 sprintf(string, "%d, %d",
2345 mwindow->session->cwindow_output_x,
2346 mwindow->session->cwindow_output_y);
2347 current->update(string);
2348 sprintf(string, "%.0f, %.0f",
2349 mwindow->edl->session->ruler_x1,
2350 mwindow->edl->session->ruler_y1);
2351 point1->update(string);
2352 sprintf(string, "%.0f, %.0f",
2353 mwindow->edl->session->ruler_x2,
2354 mwindow->edl->session->ruler_y2);
2355 point2->update(string);
2357 sprintf(string, _("%0.01f pixels"), distance_value);
2358 distance->update(string);
2359 sprintf(string, "%0.02f %c", angle_value, 0xb0);
2360 angle->update(string);
2363 void CWindowRulerGUI::handle_event()