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 int previous_tool = current_tool;
87 current_tool = operation;
91 new_gui = new CWindowEyedropGUI(mwindow, this);
94 new_gui = new CWindowCropGUI(mwindow, this);
97 new_gui = new CWindowCameraGUI(mwindow, this);
99 case CWINDOW_PROJECTOR:
100 new_gui = new CWindowProjectorGUI(mwindow, this);
103 new_gui = new CWindowMaskGUI(mwindow, this);
106 new_gui = new CWindowRulerGUI(mwindow, this);
108 case CWINDOW_PROTECT:
109 mwindow->edl->session->tool_window = 0;
110 gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]->update(0);
118 //printf("CWindowTool::start_tool 1\n");
124 // Wait for previous tool GUI to finish
125 output_lock->lock("CWindowTool::start_tool");
126 this->tool_gui = new_gui;
127 tool_gui->create_objects();
128 if( previous_tool == CWINDOW_PROTECT || previous_tool == CWINDOW_NONE ) {
129 mwindow->edl->session->tool_window = 1;
130 gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]->update(1);
132 update_show_window();
134 // Signal thread to run next tool GUI
135 input_lock->unlock();
137 //printf("CWindowTool::start_tool 1\n");
142 tool_gui->lock_window("CWindowTool::start_tool");
144 tool_gui->unlock_window();
147 //printf("CWindowTool::start_tool 2\n");
152 void CWindowTool::stop_tool()
156 tool_gui->lock_window("CWindowTool::stop_tool");
157 tool_gui->set_done(0);
158 tool_gui->unlock_window();
162 void CWindowTool::show_tool()
164 if(tool_gui && mwindow->edl->session->tool_window)
166 tool_gui->lock_window("CWindowTool::show_tool");
167 tool_gui->show_window();
168 tool_gui->unlock_window();
172 void CWindowTool::hide_tool()
174 if(tool_gui && mwindow->edl->session->tool_window)
176 tool_gui->lock_window("CWindowTool::show_tool");
177 tool_gui->hide_window();
178 tool_gui->unlock_window();
183 void CWindowTool::run()
187 input_lock->lock("CWindowTool::run");
190 tool_gui->run_window();
191 tool_gui_lock->lock("CWindowTool::run");
194 tool_gui_lock->unlock();
196 output_lock->unlock();
200 void CWindowTool::update_show_window()
204 tool_gui->lock_window("CWindowTool::update_show_window");
206 if(mwindow->edl->session->tool_window)
209 tool_gui->show_window();
212 tool_gui->hide_window();
215 tool_gui->unlock_window();
219 void CWindowTool::raise_window()
223 gui->unlock_window();
224 tool_gui->lock_window("CWindowTool::raise_window");
225 tool_gui->raise_window();
226 tool_gui->unlock_window();
227 gui->lock_window("CWindowTool::raise_window");
231 void CWindowTool::update_values()
233 tool_gui_lock->lock("CWindowTool::update_values");
236 tool_gui->lock_window("CWindowTool::update_values");
239 tool_gui->unlock_window();
241 tool_gui_lock->unlock();
250 CWindowToolGUI::CWindowToolGUI(MWindow *mwindow,
256 mwindow->session->ctool_x,
257 mwindow->session->ctool_y,
266 this->mwindow = mwindow;
267 this->thread = thread;
268 current_operation = 0;
271 CWindowToolGUI::~CWindowToolGUI()
275 int CWindowToolGUI::close_event()
279 mwindow->edl->session->tool_window = 0;
284 thread->gui->lock_window("CWindowToolGUI::close_event");
285 thread->gui->composite_panel->set_operation(mwindow->edl->session->cwindow_operation);
286 thread->gui->flush();
287 thread->gui->unlock_window();
289 lock_window("CWindowToolGUI::close_event");
293 int CWindowToolGUI::keypress_event()
297 switch( get_keypress() ) {
300 return close_event();
313 resend_event(thread->gui);
320 int CWindowToolGUI::translation_event()
322 mwindow->session->ctool_x = get_x();
323 mwindow->session->ctool_y = get_y();
332 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value, int log_increment = 0)
333 : BC_TumbleTextBox(gui, (float)value, (float)-65536, (float)65536, x, y, 100)
336 set_log_floatincrement(log_increment);
339 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
340 : BC_TumbleTextBox(gui, (int64_t)value, (int64_t)-65536, (int64_t)65536, x, y, 100)
344 int CWindowCoord::handle_event()
346 gui->event_caller = this;
352 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
353 : BC_GenericButton(x, y, _("Do it"))
355 this->mwindow = mwindow;
358 int CWindowCropOK::handle_event()
360 mwindow->crop_video();
365 int CWindowCropOK::keypress_event()
367 if(get_keypress() == 0xd)
381 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
382 : CWindowToolGUI(mwindow,
384 _(PROGRAM_NAME ": Crop"),
391 CWindowCropGUI::~CWindowCropGUI()
395 void CWindowCropGUI::create_objects()
400 lock_window("CWindowCropGUI::create_objects");
402 int pad = MAX(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1),
403 BC_Title::calculate_h(this, "X")) + 5;
404 add_subwindow(title = new BC_Title(x, y, "X1:"));
405 column1 = MAX(column1, title->get_w());
407 add_subwindow(title = new BC_Title(x, y, _("W:")));
408 column1 = MAX(column1, title->get_w());
410 add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
414 x1 = new CWindowCoord(thread->tool_gui, x, y,
415 mwindow->edl->session->crop_x1);
416 x1->create_objects();
418 width = new CWindowCoord(thread->tool_gui, x, y,
419 mwindow->edl->session->crop_x2 - mwindow->edl->session->crop_x1);
420 width->create_objects();
423 x += x1->get_w() + 10;
426 add_subwindow(title = new BC_Title(x, y, "Y1:"));
427 column2 = MAX(column2, title->get_w());
429 add_subwindow(title = new BC_Title(x, y, _("H:")));
430 column2 = MAX(column2, title->get_w());
435 y1 = new CWindowCoord(thread->tool_gui, x, y,
436 mwindow->edl->session->crop_y1);
437 y1->create_objects();
439 height = new CWindowCoord(thread->tool_gui, x, y,
440 mwindow->edl->session->crop_y2 - mwindow->edl->session->crop_y1);
441 height->create_objects();
445 void CWindowCropGUI::handle_event()
448 new_x1 = atol(x1->get_text());
449 new_y1 = atol(y1->get_text());
450 if(new_x1 != mwindow->edl->session->crop_x1)
452 mwindow->edl->session->crop_x2 = new_x1 +
453 mwindow->edl->session->crop_x2 -
454 mwindow->edl->session->crop_x1;
455 mwindow->edl->session->crop_x1 = new_x1;
457 if(new_y1 != mwindow->edl->session->crop_y1)
459 mwindow->edl->session->crop_y2 = new_y1 +
460 mwindow->edl->session->crop_y2 -
461 mwindow->edl->session->crop_y1;
462 mwindow->edl->session->crop_y1 = atol(y1->get_text());
464 mwindow->edl->session->crop_x2 = atol(width->get_text()) +
465 mwindow->edl->session->crop_x1;
466 mwindow->edl->session->crop_y2 = atol(height->get_text()) +
467 mwindow->edl->session->crop_y1;
469 mwindow->cwindow->gui->lock_window("CWindowCropGUI::handle_event");
470 mwindow->cwindow->gui->canvas->draw_refresh();
471 mwindow->cwindow->gui->unlock_window();
474 void CWindowCropGUI::update()
476 x1->update((int64_t)mwindow->edl->session->crop_x1);
477 y1->update((int64_t)mwindow->edl->session->crop_y1);
478 width->update((int64_t)mwindow->edl->session->crop_x2 -
479 mwindow->edl->session->crop_x1);
480 height->update((int64_t)mwindow->edl->session->crop_y2 -
481 mwindow->edl->session->crop_y1);
485 CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
486 : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 290)
490 CWindowEyedropGUI::~CWindowEyedropGUI()
494 void CWindowEyedropGUI::create_objects()
496 int margin = mwindow->theme->widget_border;
499 int x2 = 70, x3 = x2 + 60;
500 lock_window("CWindowEyedropGUI::create_objects");
501 BC_Title *title0, *title1, *title2, *title3, *title4, *title5, *title6, *title7;
502 add_subwindow(title0 = new BC_Title(x, y,_("X,Y:")));
503 y += title0->get_h() + margin;
504 add_subwindow(title7 = new BC_Title(x, y, _("Radius:")));
505 y += BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1) + margin;
507 add_subwindow(title1 = new BC_Title(x, y, _("Red:")));
508 y += title1->get_h() + margin;
509 add_subwindow(title2 = new BC_Title(x, y, _("Green:")));
510 y += title2->get_h() + margin;
511 add_subwindow(title3 = new BC_Title(x, y, _("Blue:")));
512 y += title3->get_h() + margin;
514 add_subwindow(title4 = new BC_Title(x, y, "Y:"));
515 y += title4->get_h() + margin;
516 add_subwindow(title5 = new BC_Title(x, y, "U:"));
517 y += title5->get_h() + margin;
518 add_subwindow(title6 = new BC_Title(x, y, "V:"));
520 add_subwindow(current = new BC_Title(x2, title0->get_y(), ""));
522 radius = new CWindowCoord(this, x2, title7->get_y(),
523 mwindow->edl->session->eyedrop_radius);
524 radius->create_objects();
525 radius->set_boundaries((int64_t)0, (int64_t)255);
527 add_subwindow(red = new BC_Title(x2, title1->get_y(), "0"));
528 add_subwindow(green = new BC_Title(x2, title2->get_y(), "0"));
529 add_subwindow(blue = new BC_Title(x2, title3->get_y(), "0"));
530 add_subwindow(rgb_hex = new BC_Title(x3, red->get_y(), "#000000"));
532 add_subwindow(this->y = new BC_Title(x2, title4->get_y(), "0"));
533 add_subwindow(this->u = new BC_Title(x2, title5->get_y(), "0"));
534 add_subwindow(this->v = new BC_Title(x2, title6->get_y(), "0"));
535 add_subwindow(yuv_hex = new BC_Title(x3, this->y->get_y(), "#000000"));
537 y = title6->get_y() + this->v->get_h() + 2*margin;
538 add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
539 y += sample->get_h() + margin;
540 add_subwindow(use_max = new CWindowEyedropCheckBox(mwindow, this, x, y));
545 void CWindowEyedropGUI::update()
547 char string[BCTEXTLEN];
548 sprintf(string, "%d, %d",
549 thread->gui->eyedrop_x,
550 thread->gui->eyedrop_y);
551 current->update(string);
553 radius->update((int64_t)mwindow->edl->session->eyedrop_radius);
555 LocalSession *local_session = mwindow->edl->local_session;
556 int use_max = local_session->use_max;
557 float r = use_max ? local_session->red_max : local_session->red;
558 float g = use_max ? local_session->green_max : local_session->green;
559 float b = use_max ? local_session->blue_max : local_session->blue;
560 this->red->update(r);
561 this->green->update(g);
562 this->blue->update(b);
564 int rx = 255*r + 0.5; bclamp(rx,0,255);
565 int gx = 255*g + 0.5; bclamp(gx,0,255);
566 int bx = 255*b + 0.5; bclamp(bx,0,255);
567 char rgb_text[BCSTRLEN];
568 sprintf(rgb_text, "#%02x%02x%02x", rx, gx, bx);
569 rgb_hex->update(rgb_text);
572 YUV::yuv.rgb_to_yuv_f(r, g, b, y, u, v);
574 this->u->update(u); u += 0.5;
575 this->v->update(v); v += 0.5;
577 int yx = 255*y + 0.5; bclamp(yx,0,255);
578 int ux = 255*u + 0.5; bclamp(ux,0,255);
579 int vx = 255*v + 0.5; bclamp(vx,0,255);
580 char yuv_text[BCSTRLEN];
581 sprintf(yuv_text, "#%02x%02x%02x", yx, ux, vx);
582 yuv_hex->update(yuv_text);
584 int rgb = (rx << 16) | (gx << 8) | (bx << 0);
585 sample->set_color(rgb);
586 sample->draw_box(0, 0, sample->get_w(), sample->get_h());
587 sample->set_color(BLACK);
588 sample->draw_rectangle(0, 0, sample->get_w(), sample->get_h());
592 void CWindowEyedropGUI::handle_event()
594 int new_radius = atoi(radius->get_text());
595 if(new_radius != mwindow->edl->session->eyedrop_radius)
597 CWindowGUI *gui = mwindow->cwindow->gui;
598 if(gui->eyedrop_visible)
600 gui->lock_window("CWindowEyedropGUI::handle_event");
603 gui->canvas->do_eyedrop(rerender, 0, 1);
606 mwindow->edl->session->eyedrop_radius = new_radius;
608 if(gui->eyedrop_visible)
612 gui->canvas->do_eyedrop(rerender, 0, 1);
613 gui->unlock_window();
620 /* Buttons to control Keyframe-Curve-Mode for Projector or Camera */
622 // Configuration for all possible Keyframe Curve Mode toggles
624 FloatAuto::t_mode mode;
630 const _CVD Camera_Crv_Smooth =
634 N_("\"smooth\" Curve on current Camera Keyframes")
636 const _CVD Camera_Crv_Linear =
640 N_("\"linear\" Curve on current Camera Keyframes")
642 const _CVD Projector_Crv_Smooth =
646 N_("\"smooth\" Curve on current Projector Keyframes")
648 const _CVD Projector_Crv_Linear =
652 N_("\"linear\" Curve on current Projector Keyframes")
655 // Implementation Class für Keyframe Curve Mode buttons
657 // This button reflects the state of the "current" keyframe
658 // (the nearest keyframe on the left) for all three automation
659 // lines together. Clicking on this button (re)sets the curve
660 // mode for the three "current" keyframes simultanously, but
661 // never creates a new keyframe.
663 class CWindowCurveToggle : public BC_Toggle
666 CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
667 void check_toggle_state(FloatAuto *x, FloatAuto *y, FloatAuto *z);
676 CWindowCurveToggle::CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
677 : BC_Toggle(x, y, mwindow->theme->get_image_set(mode.icon_id), false),
681 this->mwindow = mwindow;
682 set_tooltip(_(cfg.tooltip));
685 void CWindowCurveToggle::check_toggle_state(FloatAuto *x, FloatAuto *y, FloatAuto *z)
687 // the toggle state is only set to ON if all
688 // three automation lines have the same curve mode.
689 // For mixed states the toggle stays off.
690 set_value( x->curve_mode == this->cfg.mode &&
691 y->curve_mode == this->cfg.mode &&
692 z->curve_mode == this->cfg.mode
693 ,true // redraw to show new state
697 int CWindowCurveToggle::handle_event()
699 Track *track = mwindow->cwindow->calculate_affected_track();
701 FloatAuto *x=0, *y=0, *z=0;
702 mwindow->cwindow->calculate_affected_autos(track,
703 &x, &y, &z, cfg.use_camera, 0,0,0); // don't create new keyframe
704 if( x ) x->change_curve_mode(cfg.mode);
705 if( y ) y->change_curve_mode(cfg.mode);
706 if( z ) z->change_curve_mode(cfg.mode);
709 gui->update_preview();
716 CWindowEyedropCheckBox::CWindowEyedropCheckBox(MWindow *mwindow,
717 CWindowEyedropGUI *gui, int x, int y)
718 : BC_CheckBox(x, y, mwindow->edl->local_session->use_max, _("Use maximum"))
720 this->mwindow = mwindow;
724 int CWindowEyedropCheckBox::handle_event()
726 mwindow->edl->local_session->use_max = get_value();
733 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
734 : CWindowToolGUI(mwindow,
736 _(PROGRAM_NAME ": Camera"),
741 CWindowCameraGUI::~CWindowCameraGUI()
745 void CWindowCameraGUI::create_objects()
747 int x = 10, y = 10, x1;
748 Track *track = mwindow->cwindow->calculate_affected_track();
749 FloatAuto *x_auto = 0, *y_auto = 0, *z_auto = 0;
753 lock_window("CWindowCameraGUI::create_objects");
755 mwindow->cwindow->calculate_affected_autos(track,
756 &x_auto, &y_auto, &z_auto, 1, 0, 0, 0);
759 add_subwindow(title = new BC_Title(x, y, "X:"));
761 this->x = new CWindowCoord(this, x, y,
762 x_auto ? x_auto->get_value() : (float)0);
763 this->x->create_objects();
768 add_subwindow(title = new BC_Title(x, y, "Y:"));
770 this->y = new CWindowCoord(this, x, y,
771 y_auto ? y_auto->get_value() : (float)0);
772 this->y->create_objects();
775 add_subwindow(title = new BC_Title(x, y, "Z:"));
777 this->z = new CWindowCoord(this, x, y,
778 z_auto ? z_auto->get_value() : (float)1);
779 this->z->create_objects();
780 this->z->set_increment(0.01);
784 add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
785 x1 += button->get_w();
786 add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
787 x1 += button->get_w();
788 add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
790 y += button->get_h();
792 add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
793 x1 += button->get_w();
794 add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
795 x1 += button->get_w();
796 add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
797 // additional Buttons to control the curve mode of the "current" keyframe
798 x1 += button->get_w() + 15;
799 add_subwindow(this->t_smooth = new CWindowCurveToggle(Camera_Crv_Smooth, mwindow, this, x1, y));
800 x1 += button->get_w();
801 add_subwindow(this->t_linear = new CWindowCurveToggle(Camera_Crv_Linear, mwindow, this, x1, y));
803 // fill in current auto keyframe values, set toggle states.
808 void CWindowCameraGUI::update_preview()
810 mwindow->gui->lock_window("CWindowCameraGUI::update_preview");
811 mwindow->restart_brender();
812 mwindow->gui->draw_overlays(1);
813 mwindow->sync_parameters(CHANGE_PARAMS);
814 mwindow->gui->unlock_window();
815 mwindow->cwindow->refresh_frame(CHANGE_NONE);
816 mwindow->cwindow->gui->lock_window("CWindowCameraGUI::update_preview");
817 mwindow->cwindow->gui->canvas->draw_refresh();
818 mwindow->cwindow->gui->unlock_window();
822 void CWindowCameraGUI::handle_event()
824 FloatAuto *x_auto = 0;
825 FloatAuto *y_auto = 0;
826 FloatAuto *z_auto = 0;
827 Track *track = mwindow->cwindow->calculate_affected_track();
830 mwindow->undo->update_undo_before(_("camera"), this);
831 if(event_caller == x)
833 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
834 track->automation->autos[AUTOMATION_CAMERA_X],
838 x_auto->set_value(atof(x->get_text()));
844 if(event_caller == y)
846 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
847 track->automation->autos[AUTOMATION_CAMERA_Y],
851 y_auto->set_value(atof(y->get_text()));
857 if(event_caller == z)
859 z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
860 track->automation->autos[AUTOMATION_CAMERA_Z],
864 float zoom = atof(z->get_text());
865 if(zoom > 100.) zoom = 100.;
867 if(zoom < 0.01) zoom = 0.01;
868 // Doesn't allow user to enter from scratch
869 // if(zoom != atof(z->get_text()))
872 z_auto->set_value(zoom);
873 mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
874 mwindow->gui->draw_overlays(1);
875 mwindow->gui->unlock_window();
881 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
885 void CWindowCameraGUI::update()
887 FloatAuto *x_auto = 0;
888 FloatAuto *y_auto = 0;
889 FloatAuto *z_auto = 0;
890 Track *track = mwindow->cwindow->calculate_affected_track();
892 mwindow->cwindow->calculate_affected_autos(track,
893 &x_auto, &y_auto, &z_auto, 1, 0, 0, 0);
897 x->update(x_auto->get_value());
899 y->update(y_auto->get_value());
901 float value = z_auto->get_value();
903 thread->gui->lock_window("CWindowCameraGUI::update");
904 thread->gui->composite_panel->cpanel_zoom->update(value);
905 thread->gui->unlock_window();
908 if( x_auto && y_auto && z_auto )
910 t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
911 t_linear->check_toggle_state(x_auto, y_auto, z_auto);
918 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
919 : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
922 this->mwindow = mwindow;
923 set_tooltip(_("Left justify"));
925 int CWindowCameraLeft::handle_event()
927 FloatAuto *x_auto = 0;
928 FloatAuto *z_auto = 0;
929 Track *track = mwindow->cwindow->calculate_affected_track();
931 mwindow->cwindow->calculate_affected_autos(track,
932 &x_auto, 0, &z_auto, 1, 1, 0, 0);
938 track->get_source_dimensions(
939 mwindow->edl->local_session->get_selectionstart(1),
945 mwindow->undo->update_undo_before(_("camera"), 0);
947 (double)track->track_w / z_auto->get_value() / 2 -
949 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
951 gui->update_preview();
959 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
960 : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
963 this->mwindow = mwindow;
964 set_tooltip(_("Center horizontal"));
966 int CWindowCameraCenter::handle_event()
968 FloatAuto *x_auto = 0;
969 Track *track = mwindow->cwindow->calculate_affected_track();
971 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
972 track->automation->autos[AUTOMATION_CAMERA_X],
977 mwindow->undo->update_undo_before(_("camera"), 0);
978 x_auto->set_value(0);
980 gui->update_preview();
981 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
988 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
989 : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
992 this->mwindow = mwindow;
993 set_tooltip(_("Right justify"));
995 int CWindowCameraRight::handle_event()
997 FloatAuto *x_auto = 0;
998 FloatAuto *z_auto = 0;
999 Track *track = mwindow->cwindow->calculate_affected_track();
1001 mwindow->cwindow->calculate_affected_autos(track,
1002 &x_auto, 0, &z_auto, 1, 1, 0, 0);
1005 if(x_auto && z_auto)
1008 track->get_source_dimensions(
1009 mwindow->edl->local_session->get_selectionstart(1),
1015 mwindow->undo->update_undo_before(_("camera"), 0);
1016 x_auto->set_value( -((double)track->track_w / z_auto->get_value() / 2 -
1019 gui->update_preview();
1020 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1028 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1029 : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1032 this->mwindow = mwindow;
1033 set_tooltip(_("Top justify"));
1035 int CWindowCameraTop::handle_event()
1037 FloatAuto *y_auto = 0;
1038 FloatAuto *z_auto = 0;
1039 Track *track = mwindow->cwindow->calculate_affected_track();
1041 mwindow->cwindow->calculate_affected_autos(track,
1042 0, &y_auto, &z_auto, 1, 0, 1, 0);
1045 if(y_auto && z_auto)
1048 track->get_source_dimensions(
1049 mwindow->edl->local_session->get_selectionstart(1),
1055 mwindow->undo->update_undo_before(_("camera"), 0);
1056 y_auto->set_value((double)track->track_h / z_auto->get_value() / 2 -
1059 gui->update_preview();
1060 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1068 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1069 : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1072 this->mwindow = mwindow;
1073 set_tooltip(_("Center vertical"));
1075 int CWindowCameraMiddle::handle_event()
1077 FloatAuto *y_auto = 0;
1078 Track *track = mwindow->cwindow->calculate_affected_track();
1080 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1081 track->automation->autos[AUTOMATION_CAMERA_Y], 1);
1085 mwindow->undo->update_undo_before(_("camera"), 0);
1086 y_auto->set_value(0);
1088 gui->update_preview();
1089 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1096 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1097 : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1100 this->mwindow = mwindow;
1101 set_tooltip(_("Bottom justify"));
1103 int CWindowCameraBottom::handle_event()
1105 FloatAuto *y_auto = 0;
1106 FloatAuto *z_auto = 0;
1107 Track *track = mwindow->cwindow->calculate_affected_track();
1109 mwindow->cwindow->calculate_affected_autos(track,
1110 0, &y_auto, &z_auto, 1, 0, 1, 0);
1113 if(y_auto && z_auto)
1116 track->get_source_dimensions(
1117 mwindow->edl->local_session->get_selectionstart(1),
1123 mwindow->undo->update_undo_before(_("camera"), 0);
1124 y_auto->set_value(-((double)track->track_h / z_auto->get_value() / 2 -
1127 gui->update_preview();
1128 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1136 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
1137 : CWindowToolGUI(mwindow,
1139 _(PROGRAM_NAME ": Projector"),
1144 CWindowProjectorGUI::~CWindowProjectorGUI()
1147 void CWindowProjectorGUI::create_objects()
1149 int x = 10, y = 10, x1;
1150 Track *track = mwindow->cwindow->calculate_affected_track();
1151 FloatAuto *x_auto = 0;
1152 FloatAuto *y_auto = 0;
1153 FloatAuto *z_auto = 0;
1157 lock_window("CWindowProjectorGUI::create_objects");
1159 mwindow->cwindow->calculate_affected_autos(track,
1160 &x_auto, &y_auto, &z_auto, 0, 0, 0, 0);
1163 add_subwindow(title = new BC_Title(x, y, "X:"));
1164 x += title->get_w();
1165 this->x = new CWindowCoord(this, x, y,
1166 x_auto ? x_auto->get_value() : (float)0);
1167 this->x->create_objects();
1170 add_subwindow(title = new BC_Title(x, y, "Y:"));
1171 x += title->get_w();
1172 this->y = new CWindowCoord(this, x, y,
1173 y_auto ? y_auto->get_value() : (float)0);
1174 this->y->create_objects();
1177 add_subwindow(title = new BC_Title(x, y, "Z:"));
1178 x += title->get_w();
1179 this->z = new CWindowCoord(this, x, y,
1180 z_auto ? z_auto->get_value() : (float)1);
1181 this->z->create_objects();
1182 this->z->set_increment(0.01);
1186 add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
1187 x1 += button->get_w();
1188 add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
1189 x1 += button->get_w();
1190 add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
1192 y += button->get_h();
1194 add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
1195 x1 += button->get_w();
1196 add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
1197 x1 += button->get_w();
1198 add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
1200 // additional Buttons to control the curve mode of the "current" keyframe
1201 x1 += button->get_w() + 15;
1202 add_subwindow(this->t_smooth = new CWindowCurveToggle(Projector_Crv_Smooth, mwindow, this, x1, y));
1203 x1 += button->get_w();
1204 add_subwindow(this->t_linear = new CWindowCurveToggle(Projector_Crv_Linear, mwindow, this, x1, y));
1206 // fill in current auto keyframe values, set toggle states.
1211 void CWindowProjectorGUI::update_preview()
1213 mwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
1214 mwindow->restart_brender();
1215 mwindow->sync_parameters(CHANGE_PARAMS);
1216 mwindow->gui->draw_overlays(1);
1217 mwindow->gui->unlock_window();
1218 mwindow->cwindow->refresh_frame(CHANGE_NONE);
1219 mwindow->cwindow->gui->lock_window("CWindowProjectorGUI::update_preview");
1220 mwindow->cwindow->gui->canvas->draw_refresh();
1221 mwindow->cwindow->gui->unlock_window();
1224 void CWindowProjectorGUI::handle_event()
1226 FloatAuto *x_auto = 0;
1227 FloatAuto *y_auto = 0;
1228 FloatAuto *z_auto = 0;
1229 Track *track = mwindow->cwindow->calculate_affected_track();
1233 mwindow->undo->update_undo_before(_("projector"), this);
1234 if(event_caller == x)
1236 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1237 track->automation->autos[AUTOMATION_PROJECTOR_X],
1241 x_auto->set_value(atof(x->get_text()));
1247 if(event_caller == y)
1249 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1250 track->automation->autos[AUTOMATION_PROJECTOR_Y],
1254 y_auto->set_value(atof(y->get_text()));
1260 if(event_caller == z)
1262 z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1263 track->automation->autos[AUTOMATION_PROJECTOR_Z],
1267 float zoom = atof(z->get_text());
1268 if(zoom > 100.) zoom = 100.;
1269 else if(zoom < 0.01) zoom = 0.01;
1270 // if (zoom != atof(z->get_text()))
1272 z_auto->set_value(zoom);
1274 mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
1275 mwindow->gui->draw_overlays(1);
1276 mwindow->gui->unlock_window();
1282 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1286 void CWindowProjectorGUI::update()
1288 FloatAuto *x_auto = 0;
1289 FloatAuto *y_auto = 0;
1290 FloatAuto *z_auto = 0;
1291 Track *track = mwindow->cwindow->calculate_affected_track();
1293 mwindow->cwindow->calculate_affected_autos(track,
1294 &x_auto, &y_auto, &z_auto, 0, 0, 0, 0);
1298 x->update(x_auto->get_value());
1300 y->update(y_auto->get_value());
1302 float value = z_auto->get_value();
1304 thread->gui->lock_window("CWindowProjectorGUI::update");
1305 thread->gui->composite_panel->cpanel_zoom->update(value);
1306 thread->gui->unlock_window();
1309 if( x_auto && y_auto && z_auto )
1311 t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
1312 t_linear->check_toggle_state(x_auto, y_auto, z_auto);
1316 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1317 : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
1320 this->mwindow = mwindow;
1321 set_tooltip(_("Left justify"));
1323 int CWindowProjectorLeft::handle_event()
1325 FloatAuto *x_auto = 0;
1326 FloatAuto *z_auto = 0;
1327 Track *track = mwindow->cwindow->calculate_affected_track();
1329 mwindow->cwindow->calculate_affected_autos(track,
1330 &x_auto, 0, &z_auto, 0, 1, 0, 0);
1332 if(x_auto && z_auto)
1334 mwindow->undo->update_undo_before(_("projector"), 0);
1335 x_auto->set_value( (double)track->track_w * z_auto->get_value() / 2 -
1336 (double)mwindow->edl->session->output_w / 2 );
1338 gui->update_preview();
1339 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1346 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1347 : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
1350 this->mwindow = mwindow;
1351 set_tooltip(_("Center horizontal"));
1353 int CWindowProjectorCenter::handle_event()
1355 FloatAuto *x_auto = 0;
1356 Track *track = mwindow->cwindow->calculate_affected_track();
1358 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1359 track->automation->autos[AUTOMATION_PROJECTOR_X],
1364 mwindow->undo->update_undo_before(_("projector"), 0);
1365 x_auto->set_value(0);
1367 gui->update_preview();
1368 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1375 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1376 : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
1379 this->mwindow = mwindow;
1380 set_tooltip(_("Right justify"));
1382 int CWindowProjectorRight::handle_event()
1384 FloatAuto *x_auto = 0;
1385 FloatAuto *z_auto = 0;
1386 Track *track = mwindow->cwindow->calculate_affected_track();
1388 mwindow->cwindow->calculate_affected_autos(track,
1389 &x_auto, 0, &z_auto, 0, 1, 0, 0);
1392 if(x_auto && z_auto)
1394 mwindow->undo->update_undo_before(_("projector"), 0);
1395 x_auto->set_value( -((double)track->track_w * z_auto->get_value() / 2 -
1396 (double)mwindow->edl->session->output_w / 2));
1398 gui->update_preview();
1399 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1406 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1407 : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1410 this->mwindow = mwindow;
1411 set_tooltip(_("Top justify"));
1413 int CWindowProjectorTop::handle_event()
1415 FloatAuto *y_auto = 0;
1416 FloatAuto *z_auto = 0;
1417 Track *track = mwindow->cwindow->calculate_affected_track();
1419 mwindow->cwindow->calculate_affected_autos(track,
1420 0, &y_auto, &z_auto, 0, 0, 1, 0);
1423 if(y_auto && z_auto)
1425 mwindow->undo->update_undo_before(_("projector"), 0);
1426 y_auto->set_value( (double)track->track_h * z_auto->get_value() / 2 -
1427 (double)mwindow->edl->session->output_h / 2 );
1429 gui->update_preview();
1430 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1437 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1438 : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1441 this->mwindow = mwindow;
1442 set_tooltip(_("Center vertical"));
1444 int CWindowProjectorMiddle::handle_event()
1446 FloatAuto *y_auto = 0;
1447 Track *track = mwindow->cwindow->calculate_affected_track();
1449 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1450 track->automation->autos[AUTOMATION_PROJECTOR_Y], 1);
1454 mwindow->undo->update_undo_before(_("projector"), 0);
1455 y_auto->set_value(0);
1457 gui->update_preview();
1458 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1465 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1466 : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1469 this->mwindow = mwindow;
1470 set_tooltip(_("Bottom justify"));
1472 int CWindowProjectorBottom::handle_event()
1474 FloatAuto *y_auto = 0;
1475 FloatAuto *z_auto = 0;
1476 Track *track = mwindow->cwindow->calculate_affected_track();
1478 mwindow->cwindow->calculate_affected_autos(track,
1479 0, &y_auto, &z_auto, 0, 0, 1, 0);
1482 if(y_auto && z_auto)
1484 mwindow->undo->update_undo_before(_("projector"), 0);
1485 y_auto->set_value( -((double)track->track_h * z_auto->get_value() / 2 -
1486 (double)mwindow->edl->session->output_h / 2));
1488 gui->update_preview();
1489 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1496 CWindowMaskMode::CWindowMaskMode(MWindow *mwindow,
1497 CWindowToolGUI *gui, int x, int y, const char *text)
1498 : BC_PopupMenu(x, y, 220, text, 1)
1500 this->mwindow = mwindow;
1504 void CWindowMaskMode::create_objects()
1506 add_item(new BC_MenuItem(mode_to_text(MASK_MULTIPLY_ALPHA)));
1507 add_item(new BC_MenuItem(mode_to_text(MASK_SUBTRACT_ALPHA)));
1510 char* CWindowMaskMode::mode_to_text(int mode)
1514 case MASK_MULTIPLY_ALPHA:
1515 return _("Multiply alpha");
1518 case MASK_SUBTRACT_ALPHA:
1519 return _("Subtract alpha");
1523 return _("Subtract alpha");
1526 int CWindowMaskMode::text_to_mode(char *text)
1528 if(!strcasecmp(text, _("Multiply alpha")))
1529 return MASK_MULTIPLY_ALPHA;
1531 if(!strcasecmp(text, _("Subtract alpha")))
1532 return MASK_SUBTRACT_ALPHA;
1534 return MASK_SUBTRACT_ALPHA;
1537 int CWindowMaskMode::handle_event()
1544 // Get existing keyframe
1545 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1548 mwindow->undo->update_undo_before(_("mask mode"), 0);
1549 #ifdef USE_KEYFRAME_SPANNING
1550 // Create temp keyframe
1551 MaskAuto temp_keyframe(mwindow->edl, autos);
1552 temp_keyframe.copy_data(keyframe);
1554 temp_keyframe.mode = text_to_mode(get_text());
1555 // Commit change to span of keyframes
1556 autos->update_parameter(&temp_keyframe);
1558 ((MaskAuto*)autos->default_auto)->mode =
1559 text_to_mode(get_text());
1561 mwindow->undo->update_undo_after(_("mask mode"), LOAD_AUTOMATION);
1564 //printf("CWindowMaskMode::handle_event 1\n");
1565 gui->update_preview();
1576 CWindowMaskDelete::CWindowMaskDelete(MWindow *mwindow,
1577 CWindowToolGUI *gui,
1580 : BC_GenericButton(x, y, _("Delete"))
1582 this->mwindow = mwindow;
1586 int CWindowMaskDelete::handle_event()
1593 int total_points = 0;
1595 // Get existing keyframe
1596 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1600 mwindow->undo->update_undo_before(_("mask delete"), 0);
1602 #ifdef USE_KEYFRAME_SPANNING
1603 // Create temp keyframe
1604 MaskAuto temp_keyframe(mwindow->edl, autos);
1605 temp_keyframe.copy_data(keyframe);
1607 SubMask *submask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
1609 submask->points.remove_all_objects();
1611 for(int i = mwindow->cwindow->gui->affected_point;
1612 i < submask->points.total - 1;
1615 *submask->points.values[i] = *submask->points.values[i + 1];
1618 if(submask->points.total)
1620 submask->points.remove_object(
1621 submask->points.values[submask->points.total - 1]);
1623 total_points = submask->points.total;
1625 // Commit change to span of keyframes
1626 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->update_parameter(&temp_keyframe);
1628 for(MaskAuto *current = (MaskAuto*)autos->default_auto;
1631 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1633 submask->points.remove_all_objects();
1635 for(int i = mwindow->cwindow->gui->affected_point;
1636 i < submask->points.total - 1;
1639 *submask->points.values[i] = *submask->points.values[i + 1];
1642 if(submask->points.total)
1644 submask->points.remove_object(
1645 submask->points.values[submask->points.total - 1]);
1647 total_points = submask->points.total;
1649 if(current == (MaskAuto*)autos->default_auto)
1650 current = (MaskAuto*)autos->first;
1652 current = (MaskAuto*)NEXT;
1655 if( mwindow->cwindow->gui->affected_point >= total_points )
1656 mwindow->cwindow->gui->affected_point =
1657 total_points > 0 ? total_points-1 : 0;
1660 gui->update_preview();
1661 mwindow->undo->update_undo_after(_("mask delete"), LOAD_AUTOMATION);
1668 int CWindowMaskDelete::keypress_event()
1670 if(get_keypress() == BACKSPACE ||
1671 get_keypress() == DELETE)
1672 return handle_event();
1677 // CWindowMaskCycleNext::CWindowMaskCycleNext(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1678 // : BC_GenericButton(x, y, _("Cycle next"))
1680 // this->mwindow = mwindow;
1683 // int CWindowMaskCycleNext::handle_event()
1685 // MaskAuto *keyframe;
1686 // MaskAutos *autos;
1688 // MaskPoint *point;
1690 // ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1694 // // Should apply to all keyframes
1695 // if(keyframe && mask->points.total)
1697 // temp = mask->points.values[0];
1699 // for(int i = 0; i < mask->points.total - 1; i++)
1701 // mask->points.values[i] = mask->points.values[i + 1];
1703 // mask->points.values[mask->points.total - 1] = temp;
1705 // mwindow->cwindow->gui->affected_point--;
1706 // if(mwindow->cwindow->gui->affected_point < 0)
1707 // mwindow->cwindow->gui->affected_point = mask->points.total - 1;
1710 // gui->update_preview();
1716 // CWindowMaskCyclePrev::CWindowMaskCyclePrev(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1717 // : BC_GenericButton(x, y, _("Cycle prev"))
1719 // this->mwindow = mwindow;
1722 // int CWindowMaskCyclePrev::handle_event()
1724 // MaskAuto *keyframe;
1725 // MaskAutos *autos;
1727 // MaskPoint *point;
1729 // ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1731 // // Should apply to all keyframes
1733 // if(keyframe && mask->points.total)
1735 // temp = mask->points.values[mask->points.total - 1];
1737 // for(int i = mask->points.total - 1; i > 0; i--)
1739 // mask->points.values[i] = mask->points.values[i - 1];
1741 // mask->points.values[0] = temp;
1743 // mwindow->cwindow->gui->affected_point++;
1744 // if(mwindow->cwindow->gui->affected_point >= mask->points.total)
1745 // mwindow->cwindow->gui->affected_point = 0;
1748 // gui->update_preview();
1754 CWindowMaskNumber::CWindowMaskNumber(MWindow *mwindow,
1755 CWindowToolGUI *gui,
1758 : BC_TumbleTextBox(gui,
1759 (int64_t)mwindow->edl->session->cwindow_mask,
1761 (int64_t)SUBMASKS - 1,
1766 this->mwindow = mwindow;
1770 CWindowMaskNumber::~CWindowMaskNumber()
1774 int CWindowMaskNumber::handle_event()
1776 mwindow->edl->session->cwindow_mask = atol(get_text());
1778 gui->update_preview();
1783 CWindowMaskAffectedPoint::CWindowMaskAffectedPoint(MWindow *mwindow,
1784 CWindowToolGUI *gui, int x, int y)
1785 : BC_TumbleTextBox(gui,
1786 (int64_t)mwindow->cwindow->gui->affected_point,
1787 (int64_t)0, INT64_MAX, x, y, 100)
1789 this->mwindow = mwindow;
1793 CWindowMaskAffectedPoint::~CWindowMaskAffectedPoint()
1797 int CWindowMaskAffectedPoint::handle_event()
1799 int total_points = 0;
1800 int affected_point = atol(get_text());
1801 Track *track = mwindow->cwindow->calculate_affected_track();
1803 MaskAutos *autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
1804 MaskAuto *keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(autos, 0);
1806 SubMask *mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
1807 total_points = mask->points.size();
1810 int active_point = affected_point;
1811 if( affected_point >= total_points )
1812 affected_point = total_points - 1;
1813 else if( affected_point < 0 )
1815 if( active_point != affected_point )
1816 update((int64_t)affected_point);
1817 mwindow->cwindow->gui->affected_point = affected_point;
1819 gui->update_preview();
1827 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1828 : BC_TumbleTextBox(gui,
1836 this->mwindow = mwindow;
1839 CWindowMaskFeather::~CWindowMaskFeather()
1842 int CWindowMaskFeather::handle_event()
1849 #ifdef USE_KEYFRAME_SPANNING
1855 mwindow->undo->update_undo_before(_("mask feather"), this);
1857 // Get existing keyframe
1858 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe,
1859 mask, point, create_it);
1863 #ifdef USE_KEYFRAME_SPANNING
1864 // Create temp keyframe
1865 MaskAuto temp_keyframe(mwindow->edl, autos);
1866 temp_keyframe.copy_data(keyframe);
1868 temp_keyframe.feather = atof(get_text());
1869 // Commit change to span of keyframes
1870 autos->update_parameter(&temp_keyframe);
1872 keyframe->feather = atof(get_text());
1875 gui->update_preview();
1878 mwindow->undo->update_undo_after(_("mask feather"), LOAD_AUTOMATION);
1883 CWindowMaskValue::CWindowMaskValue(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1893 this->mwindow = mwindow;
1897 CWindowMaskValue::~CWindowMaskValue()
1901 int CWindowMaskValue::handle_event()
1908 #ifdef USE_KEYFRAME_SPANNING
1914 mwindow->undo->update_undo_before(_("mask value"), this);
1915 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe,
1916 mask, point, create_it);
1920 #ifdef USE_KEYFRAME_SPANNING
1921 // Create temp keyframe
1922 MaskAuto temp_keyframe(mwindow->edl, autos);
1923 temp_keyframe.copy_data(keyframe);
1925 temp_keyframe.value = get_value();
1926 // Commit change to span of keyframes
1927 autos->update_parameter(&temp_keyframe);
1929 keyframe->value = get_value();
1933 gui->update_preview();
1934 mwindow->undo->update_undo_after(_("mask value"), LOAD_AUTOMATION);
1939 CWindowMaskBeforePlugins::CWindowMaskBeforePlugins(CWindowToolGUI *gui, int x, int y)
1943 _("Apply mask before plugins"))
1948 int CWindowMaskBeforePlugins::handle_event()
1955 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 1);
1958 keyframe->apply_before_plugins = get_value();
1959 gui->update_preview();
1965 CWindowDisableOpenGLMasking::CWindowDisableOpenGLMasking(CWindowToolGUI *gui, int x, int y)
1966 : BC_CheckBox(x, y, 1, _("Disable OpenGL masking"))
1971 int CWindowDisableOpenGLMasking::handle_event()
1978 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 1);
1981 keyframe->disable_opengl_masking = get_value();
1982 gui->update_preview();
1995 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
1996 : CWindowToolGUI(mwindow, thread,
1997 _(PROGRAM_NAME ": Mask"), 330, 320)
1999 this->mwindow = mwindow;
2000 this->thread = thread;
2005 CWindowMaskGUI::~CWindowMaskGUI()
2007 lock_window("CWindowMaskGUI::~CWindowMaskGUI");
2009 delete active_point;
2014 void CWindowMaskGUI::create_objects()
2016 int x = 10, y = 10, margin = mwindow->theme->widget_border;
2017 //MaskAuto *keyframe = 0;
2018 //Track *track = mwindow->cwindow->calculate_affected_track();
2020 // keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], 0);
2022 lock_window("CWindowMaskGUI::create_objects");
2024 add_subwindow(title = new BC_Title(x, y, _("Mode:")));
2025 add_subwindow(mode = new CWindowMaskMode(mwindow,
2026 this, x + title->get_w() + margin, y, ""));
2027 mode->create_objects();
2028 y += mode->get_h() + margin;
2029 add_subwindow(title = new BC_Title(x, y, _("Value:")));
2030 add_subwindow(value = new CWindowMaskValue(mwindow, this, x + title->get_w() + margin, y));
2031 y += value->get_h() + margin;
2032 add_subwindow(delete_point = new CWindowMaskDelete(mwindow, this, x, y));
2033 int x1 = x + delete_point->get_w() + 2*margin;
2034 add_subwindow(title = new BC_Title(x1, y, _("Point:")));
2035 x1 += title->get_w() + margin;
2036 active_point = new CWindowMaskAffectedPoint(mwindow, this, x1, y);
2037 active_point->create_objects();
2038 y += delete_point->get_h() + margin;
2039 add_subwindow(title = new BC_Title(x, y, _("Mask number:")));
2040 number = new CWindowMaskNumber(mwindow,
2041 this, x + title->get_w() + margin, y);
2042 number->create_objects();
2043 y += number->get_h() + margin;
2044 add_subwindow(title = new BC_Title(x, y, _("Feather:")));
2045 feather = new CWindowMaskFeather(mwindow,
2046 this, x + title->get_w() + margin, y);
2047 feather->create_objects();
2048 y += feather->get_h() + margin;
2049 add_subwindow(title = new BC_Title(x, y, "X:"));
2050 x += title->get_w() + margin;
2051 this->x = new CWindowCoord(this, x, y, (float)0.0);
2052 this->x->create_objects();
2053 x += this->x->get_w() + margin;
2054 add_subwindow(title = new BC_Title(x, y, "Y:"));
2055 x += title->get_w() + margin;
2056 this->y = new CWindowCoord(this, x, y, (float)0.0);
2057 this->y->create_objects();
2060 y += this->y->get_h() + margin;
2061 add_subwindow(title = new BC_Title(x, y, _("Press Shift to move an end point")));
2062 y += title->get_h() + margin;
2063 add_subwindow(title = new BC_Title(x, y, _("Press Ctrl to move a control point")));
2064 y += title->get_h() + margin;
2065 add_subwindow(title = new BC_Title(x, y, _("Shift+click Delete to delete the mask")));
2066 y += title->get_h() + margin;
2067 add_subwindow(title = new BC_Title(x, y, _("Press Alt to translate the mask")));
2070 add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this, 10, y));
2071 y += this->apply_before_plugins->get_h() + margin;
2072 add_subwindow(this->disable_opengl_masking = new CWindowDisableOpenGLMasking(this, 10, y));
2078 void CWindowMaskGUI::get_keyframe(Track* &track,
2080 MaskAuto* &keyframe,
2088 track = mwindow->cwindow->calculate_affected_track();
2091 autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
2092 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(
2098 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
2105 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2106 mwindow->cwindow->gui->affected_point >= 0)
2108 point = mask->points.values[mwindow->cwindow->gui->affected_point];
2113 void CWindowMaskGUI::update()
2120 //printf("CWindowMaskGUI::update 1\n");
2121 get_keyframe(track, autos, keyframe, mask, point, 0);
2123 double position = mwindow->edl->local_session->get_selectionstart(1);
2124 position = mwindow->edl->align_to_frame(position, 0);
2127 int64_t position_i = track->to_units(position, 0);
2131 x->update(point->x);
2132 y->update(point->y);
2137 feather->update((int64_t)autos->get_feather(position_i, PLAY_FORWARD));
2138 value->update((int64_t)autos->get_value(position_i, PLAY_FORWARD));
2139 apply_before_plugins->update((int64_t)keyframe->apply_before_plugins);
2140 disable_opengl_masking->update((int64_t)keyframe->disable_opengl_masking);
2144 //printf("CWindowMaskGUI::update 1\n");
2145 active_point->update((int64_t)mwindow->cwindow->gui->affected_point);
2146 number->update((int64_t)mwindow->edl->session->cwindow_mask);
2148 //printf("CWindowMaskGUI::update 1\n");
2151 #ifdef USE_KEYFRAME_SPANNING
2153 CWindowMaskMode::mode_to_text(keyframe->mode));
2156 CWindowMaskMode::mode_to_text(((MaskAuto*)autos->default_auto)->mode));
2159 //printf("CWindowMaskGUI::update 2\n");
2162 void CWindowMaskGUI::handle_event()
2169 get_keyframe(track, autos, keyframe, mask, point, 0);
2171 mwindow->undo->update_undo_before(_("mask point"), this);
2175 #ifdef USE_KEYFRAME_SPANNING
2176 // Create temp keyframe
2177 MaskAuto temp_keyframe(mwindow->edl, autos);
2178 temp_keyframe.copy_data(keyframe);
2179 // Get affected point in temp keyframe
2180 mask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
2181 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2182 mwindow->cwindow->gui->affected_point >= 0)
2184 point = mask->points.values[mwindow->cwindow->gui->affected_point];
2189 point->x = atof(x->get_text());
2190 point->y = atof(y->get_text());
2191 // Commit to spanned keyframes
2192 autos->update_parameter(&temp_keyframe);
2195 point->x = atof(x->get_text());
2196 point->y = atof(y->get_text());
2201 mwindow->undo->update_undo_after(_("mask point"), LOAD_AUTOMATION);
2204 void CWindowMaskGUI::update_preview()
2206 mwindow->gui->lock_window("CWindowMaskGUI::update_preview");
2207 mwindow->restart_brender();
2208 mwindow->sync_parameters(CHANGE_PARAMS);
2209 mwindow->gui->draw_overlays(1);
2210 mwindow->gui->unlock_window();
2211 mwindow->cwindow->refresh_frame(CHANGE_NONE);
2212 mwindow->cwindow->gui->lock_window("CWindowMaskGUI::update_preview");
2213 mwindow->cwindow->gui->canvas->draw_refresh();
2214 mwindow->cwindow->gui->unlock_window();
2218 CWindowRulerGUI::CWindowRulerGUI(MWindow *mwindow, CWindowTool *thread)
2219 : CWindowToolGUI(mwindow,
2221 _(PROGRAM_NAME ": Ruler"),
2227 CWindowRulerGUI::~CWindowRulerGUI()
2231 void CWindowRulerGUI::create_objects()
2233 int x = 10, y = 10, x1 = 100;
2236 lock_window("CWindowRulerGUI::create_objects");
2237 add_subwindow(title = new BC_Title(x, y, _("Current:")));
2238 add_subwindow(current = new BC_TextBox(x1, y, 200, 1, ""));
2239 y += title->get_h() + 5;
2240 add_subwindow(title = new BC_Title(x, y, _("Point 1:")));
2241 add_subwindow(point1 = new BC_TextBox(x1, y, 200, 1, ""));
2242 y += title->get_h() + 5;
2243 add_subwindow(title = new BC_Title(x, y, _("Point 2:")));
2244 add_subwindow(point2 = new BC_TextBox(x1, y, 200, 1, ""));
2245 y += title->get_h() + 5;
2246 add_subwindow(title = new BC_Title(x, y, _("Deltas:")));
2247 add_subwindow(deltas = new BC_TextBox(x1, y, 200, 1, ""));
2248 y += title->get_h() + 5;
2249 add_subwindow(title = new BC_Title(x, y, _("Distance:")));
2250 add_subwindow(distance = new BC_TextBox(x1, y, 200, 1, ""));
2251 y += title->get_h() + 5;
2252 add_subwindow(title = new BC_Title(x, y, _("Angle:")));
2253 add_subwindow(angle = new BC_TextBox(x1, y, 200, 1, ""));
2254 y += title->get_h() + 10;
2255 char string[BCTEXTLEN];
2257 _("Press Ctrl to lock ruler to the\nnearest 45%c%c angle."),
2258 0xc2, 0xb0); // degrees utf
2259 add_subwindow(title = new BC_Title(x,
2262 y += title->get_h() + 10;
2263 sprintf(string, _("Press Alt to translate the ruler."));
2264 add_subwindow(title = new BC_Title(x,
2271 void CWindowRulerGUI::update()
2273 char string[BCTEXTLEN];
2274 int cx = mwindow->session->cwindow_output_x;
2275 int cy = mwindow->session->cwindow_output_y;
2276 sprintf(string, "%d, %d", cx, cy);
2277 current->update(string);
2278 double x1 = mwindow->edl->session->ruler_x1;
2279 double y1 = mwindow->edl->session->ruler_y1;
2280 sprintf(string, "%.0f, %.0f", x1, y1);
2281 point1->update(string);
2282 double x2 = mwindow->edl->session->ruler_x2;
2283 double y2 = mwindow->edl->session->ruler_y2;
2284 sprintf(string, "%.0f, %.0f", x2, y2);
2285 point2->update(string);
2286 double dx = x2 - x1, dy = y2 - y1;
2287 sprintf(string, "%s%.0f, %s%.0f", (dx>=0? "+":""), dx, (dy>=0? "+":""), dy);
2288 deltas->update(string);
2289 double d = sqrt(dx*dx + dy*dy);
2290 sprintf(string, _("%0.01f pixels"), d);
2291 distance->update(string);
2292 double a = d > 0 ? (atan2(-dy, dx) * 180/M_PI) : 0.;
2293 sprintf(string, "%0.02f %c%c", a, 0xc2, 0xb0);
2294 angle->update(string);
2297 void CWindowRulerGUI::handle_event()