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"
28 #include "condition.h"
30 #include "cplayback.h"
32 #include "cwindowgui.h"
33 #include "cwindowtool.h"
35 #include "edlsession.h"
36 #include "floatauto.h"
37 #include "floatautos.h"
40 #include "localsession.h"
41 #include "mainsession.h"
44 #include "maskautos.h"
47 #include "mwindowgui.h"
50 #include "trackcanvas.h"
51 #include "transportque.h"
54 CWindowTool::CWindowTool(MWindow *mwindow, CWindowGUI *gui)
57 this->mwindow = mwindow;
61 current_tool = CWINDOW_NONE;
63 input_lock = new Condition(0, "CWindowTool::input_lock");
64 output_lock = new Condition(1, "CWindowTool::output_lock");
65 tool_gui_lock = new Mutex("CWindowTool::tool_gui_lock");
68 CWindowTool::~CWindowTool()
79 void CWindowTool::start_tool(int operation)
81 CWindowToolGUI *new_gui = 0;
84 //printf("CWindowTool::start_tool 1\n");
85 if(current_tool != operation)
87 int previous_tool = current_tool;
88 current_tool = operation;
92 new_gui = new CWindowEyedropGUI(mwindow, this);
95 new_gui = new CWindowCropGUI(mwindow, this);
98 new_gui = new CWindowCameraGUI(mwindow, this);
100 case CWINDOW_PROJECTOR:
101 new_gui = new CWindowProjectorGUI(mwindow, this);
104 new_gui = new CWindowMaskGUI(mwindow, this);
107 new_gui = new CWindowRulerGUI(mwindow, this);
109 case CWINDOW_PROTECT:
110 mwindow->edl->session->tool_window = 0;
111 gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]->update(0);
119 //printf("CWindowTool::start_tool 1\n");
125 // Wait for previous tool GUI to finish
126 output_lock->lock("CWindowTool::start_tool");
127 this->tool_gui = new_gui;
128 tool_gui->create_objects();
129 if( previous_tool == CWINDOW_PROTECT || previous_tool == CWINDOW_NONE ) {
130 mwindow->edl->session->tool_window = 1;
131 gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]->update(1);
133 update_show_window();
135 // Signal thread to run next tool GUI
136 input_lock->unlock();
138 //printf("CWindowTool::start_tool 1\n");
143 tool_gui->lock_window("CWindowTool::start_tool");
145 tool_gui->unlock_window();
148 //printf("CWindowTool::start_tool 2\n");
153 void CWindowTool::stop_tool()
157 tool_gui->lock_window("CWindowTool::stop_tool");
158 tool_gui->set_done(0);
159 tool_gui->unlock_window();
163 void CWindowTool::show_tool()
165 if(tool_gui && mwindow->edl->session->tool_window)
167 tool_gui->lock_window("CWindowTool::show_tool");
168 tool_gui->show_window();
169 tool_gui->unlock_window();
173 void CWindowTool::hide_tool()
175 if(tool_gui && mwindow->edl->session->tool_window)
177 tool_gui->lock_window("CWindowTool::show_tool");
178 tool_gui->hide_window();
179 tool_gui->unlock_window();
184 void CWindowTool::run()
188 input_lock->lock("CWindowTool::run");
191 tool_gui->run_window();
192 tool_gui_lock->lock("CWindowTool::run");
195 tool_gui_lock->unlock();
197 output_lock->unlock();
201 void CWindowTool::update_show_window()
205 tool_gui->lock_window("CWindowTool::update_show_window");
207 if(mwindow->edl->session->tool_window)
210 tool_gui->show_window();
213 tool_gui->hide_window();
216 tool_gui->unlock_window();
220 void CWindowTool::raise_window()
224 gui->unlock_window();
225 tool_gui->lock_window("CWindowTool::raise_window");
226 tool_gui->raise_window();
227 tool_gui->unlock_window();
228 gui->lock_window("CWindowTool::raise_window");
232 void CWindowTool::update_values()
234 tool_gui_lock->lock("CWindowTool::update_values");
237 tool_gui->lock_window("CWindowTool::update_values");
240 tool_gui->unlock_window();
242 tool_gui_lock->unlock();
251 CWindowToolGUI::CWindowToolGUI(MWindow *mwindow,
257 mwindow->session->ctool_x,
258 mwindow->session->ctool_y,
267 this->mwindow = mwindow;
268 this->thread = thread;
269 current_operation = 0;
272 CWindowToolGUI::~CWindowToolGUI()
276 int CWindowToolGUI::close_event()
280 mwindow->edl->session->tool_window = 0;
285 thread->gui->lock_window("CWindowToolGUI::close_event");
286 thread->gui->composite_panel->set_operation(mwindow->edl->session->cwindow_operation);
287 thread->gui->flush();
288 thread->gui->unlock_window();
290 lock_window("CWindowToolGUI::close_event");
294 int CWindowToolGUI::keypress_event()
298 switch( get_keypress() ) {
301 return close_event();
314 resend_event(thread->gui);
321 int CWindowToolGUI::translation_event()
323 mwindow->session->ctool_x = get_x();
324 mwindow->session->ctool_y = get_y();
333 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, float value, int log_increment = 0)
334 : BC_TumbleTextBox(gui, (float)value, (float)-65536, (float)65536, x, y, 100, 3)
337 set_log_floatincrement(log_increment);
340 CWindowCoord::CWindowCoord(CWindowToolGUI *gui, int x, int y, int value)
341 : BC_TumbleTextBox(gui, (int64_t)value, (int64_t)-65536, (int64_t)65536, x, y, 100, 3)
345 int CWindowCoord::handle_event()
347 gui->event_caller = this;
353 CWindowCropOK::CWindowCropOK(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
354 : BC_GenericButton(x, y, _("Do it"))
356 this->mwindow = mwindow;
359 int CWindowCropOK::handle_event()
361 mwindow->crop_video();
366 int CWindowCropOK::keypress_event()
368 if(get_keypress() == 0xd)
382 CWindowCropGUI::CWindowCropGUI(MWindow *mwindow, CWindowTool *thread)
383 : CWindowToolGUI(mwindow,
385 _(PROGRAM_NAME ": Crop"),
392 CWindowCropGUI::~CWindowCropGUI()
396 void CWindowCropGUI::create_objects()
401 lock_window("CWindowCropGUI::create_objects");
403 int pad = MAX(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1),
404 BC_Title::calculate_h(this, "X")) + 5;
405 add_subwindow(title = new BC_Title(x, y, "X1:"));
406 column1 = MAX(column1, title->get_w());
408 add_subwindow(title = new BC_Title(x, y, _("W:")));
409 column1 = MAX(column1, title->get_w());
411 add_subwindow(new CWindowCropOK(mwindow, thread->tool_gui, x, y));
415 x1 = new CWindowCoord(thread->tool_gui, x, y,
416 mwindow->edl->session->crop_x1);
417 x1->create_objects();
419 width = new CWindowCoord(thread->tool_gui, x, y,
420 mwindow->edl->session->crop_x2 - mwindow->edl->session->crop_x1);
421 width->create_objects();
424 x += x1->get_w() + 10;
427 add_subwindow(title = new BC_Title(x, y, "Y1:"));
428 column2 = MAX(column2, title->get_w());
430 add_subwindow(title = new BC_Title(x, y, _("H:")));
431 column2 = MAX(column2, title->get_w());
436 y1 = new CWindowCoord(thread->tool_gui, x, y,
437 mwindow->edl->session->crop_y1);
438 y1->create_objects();
440 height = new CWindowCoord(thread->tool_gui, x, y,
441 mwindow->edl->session->crop_y2 - mwindow->edl->session->crop_y1);
442 height->create_objects();
446 void CWindowCropGUI::handle_event()
449 new_x1 = atol(x1->get_text());
450 new_y1 = atol(y1->get_text());
451 if(new_x1 != mwindow->edl->session->crop_x1)
453 mwindow->edl->session->crop_x2 = new_x1 +
454 mwindow->edl->session->crop_x2 -
455 mwindow->edl->session->crop_x1;
456 mwindow->edl->session->crop_x1 = new_x1;
458 if(new_y1 != mwindow->edl->session->crop_y1)
460 mwindow->edl->session->crop_y2 = new_y1 +
461 mwindow->edl->session->crop_y2 -
462 mwindow->edl->session->crop_y1;
463 mwindow->edl->session->crop_y1 = atol(y1->get_text());
465 mwindow->edl->session->crop_x2 = atol(width->get_text()) +
466 mwindow->edl->session->crop_x1;
467 mwindow->edl->session->crop_y2 = atol(height->get_text()) +
468 mwindow->edl->session->crop_y1;
470 mwindow->cwindow->gui->canvas->redraw(1);
473 void CWindowCropGUI::update()
475 x1->update((int64_t)mwindow->edl->session->crop_x1);
476 y1->update((int64_t)mwindow->edl->session->crop_y1);
477 width->update((int64_t)mwindow->edl->session->crop_x2 -
478 mwindow->edl->session->crop_x1);
479 height->update((int64_t)mwindow->edl->session->crop_y2 -
480 mwindow->edl->session->crop_y1);
484 CWindowEyedropGUI::CWindowEyedropGUI(MWindow *mwindow, CWindowTool *thread)
485 : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Color"), 220, 290)
489 CWindowEyedropGUI::~CWindowEyedropGUI()
493 void CWindowEyedropGUI::create_objects()
495 int margin = mwindow->theme->widget_border;
498 int x2 = 70, x3 = x2 + 60;
499 lock_window("CWindowEyedropGUI::create_objects");
500 BC_Title *title0, *title1, *title2, *title3, *title4, *title5, *title6, *title7;
501 add_subwindow(title0 = new BC_Title(x, y,_("X,Y:")));
502 y += title0->get_h() + margin;
503 add_subwindow(title7 = new BC_Title(x, y, _("Radius:")));
504 y += BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1) + margin;
506 add_subwindow(title1 = new BC_Title(x, y, _("Red:")));
507 y += title1->get_h() + margin;
508 add_subwindow(title2 = new BC_Title(x, y, _("Green:")));
509 y += title2->get_h() + margin;
510 add_subwindow(title3 = new BC_Title(x, y, _("Blue:")));
511 y += title3->get_h() + margin;
513 add_subwindow(title4 = new BC_Title(x, y, "Y:"));
514 y += title4->get_h() + margin;
515 add_subwindow(title5 = new BC_Title(x, y, "U:"));
516 y += title5->get_h() + margin;
517 add_subwindow(title6 = new BC_Title(x, y, "V:"));
519 add_subwindow(current = new BC_Title(x2, title0->get_y(), ""));
521 radius = new CWindowCoord(this, x2, title7->get_y(),
522 mwindow->edl->session->eyedrop_radius);
523 radius->create_objects();
524 radius->set_boundaries((int64_t)0, (int64_t)255);
526 add_subwindow(red = new BC_Title(x2, title1->get_y(), "0"));
527 add_subwindow(green = new BC_Title(x2, title2->get_y(), "0"));
528 add_subwindow(blue = new BC_Title(x2, title3->get_y(), "0"));
529 add_subwindow(rgb_hex = new BC_Title(x3, red->get_y(), "#000000"));
531 add_subwindow(this->y = new BC_Title(x2, title4->get_y(), "0"));
532 add_subwindow(this->u = new BC_Title(x2, title5->get_y(), "0"));
533 add_subwindow(this->v = new BC_Title(x2, title6->get_y(), "0"));
534 add_subwindow(yuv_hex = new BC_Title(x3, this->y->get_y(), "#000000"));
536 y = title6->get_y() + this->v->get_h() + 2*margin;
537 add_subwindow(sample = new BC_SubWindow(x, y, 50, 50));
538 y += sample->get_h() + margin;
539 add_subwindow(use_max = new CWindowEyedropCheckBox(mwindow, this, x, y));
544 void CWindowEyedropGUI::update()
546 char string[BCTEXTLEN];
547 sprintf(string, "%d, %d",
548 thread->gui->eyedrop_x,
549 thread->gui->eyedrop_y);
550 current->update(string);
552 radius->update((int64_t)mwindow->edl->session->eyedrop_radius);
554 LocalSession *local_session = mwindow->edl->local_session;
555 int use_max = local_session->use_max;
556 float r = use_max ? local_session->red_max : local_session->red;
557 float g = use_max ? local_session->green_max : local_session->green;
558 float b = use_max ? local_session->blue_max : local_session->blue;
559 this->red->update(r);
560 this->green->update(g);
561 this->blue->update(b);
563 int rx = 255*r + 0.5; bclamp(rx,0,255);
564 int gx = 255*g + 0.5; bclamp(gx,0,255);
565 int bx = 255*b + 0.5; bclamp(bx,0,255);
566 char rgb_text[BCSTRLEN];
567 sprintf(rgb_text, "#%02x%02x%02x", rx, gx, bx);
568 rgb_hex->update(rgb_text);
571 YUV::yuv.rgb_to_yuv_f(r, g, b, y, u, v);
573 this->u->update(u); u += 0.5;
574 this->v->update(v); v += 0.5;
576 int yx = 255*y + 0.5; bclamp(yx,0,255);
577 int ux = 255*u + 0.5; bclamp(ux,0,255);
578 int vx = 255*v + 0.5; bclamp(vx,0,255);
579 char yuv_text[BCSTRLEN];
580 sprintf(yuv_text, "#%02x%02x%02x", yx, ux, vx);
581 yuv_hex->update(yuv_text);
583 int rgb = (rx << 16) | (gx << 8) | (bx << 0);
584 sample->set_color(rgb);
585 sample->draw_box(0, 0, sample->get_w(), sample->get_h());
586 sample->set_color(BLACK);
587 sample->draw_rectangle(0, 0, sample->get_w(), sample->get_h());
591 void CWindowEyedropGUI::handle_event()
593 int new_radius = atoi(radius->get_text());
594 if(new_radius != mwindow->edl->session->eyedrop_radius)
596 CWindowGUI *gui = mwindow->cwindow->gui;
597 if(gui->eyedrop_visible)
599 gui->lock_window("CWindowEyedropGUI::handle_event");
602 gui->canvas->do_eyedrop(rerender, 0, 1);
605 mwindow->edl->session->eyedrop_radius = new_radius;
607 if(gui->eyedrop_visible)
611 gui->canvas->do_eyedrop(rerender, 0, 1);
612 gui->unlock_window();
619 /* Buttons to control Keyframe-Curve-Mode for Projector or Camera */
621 // Configuration for all possible Keyframe Curve Mode toggles
623 FloatAuto::t_mode mode;
629 const _CVD Camera_Crv_Smooth =
633 N_("\"smooth\" Curve on current Camera Keyframes")
635 const _CVD Camera_Crv_Linear =
639 N_("\"linear\" Curve on current Camera Keyframes")
641 const _CVD Projector_Crv_Smooth =
645 N_("\"smooth\" Curve on current Projector Keyframes")
647 const _CVD Projector_Crv_Linear =
651 N_("\"linear\" Curve on current Projector Keyframes")
654 // Implementation Class für Keyframe Curve Mode buttons
656 // This button reflects the state of the "current" keyframe
657 // (the nearest keyframe on the left) for all three automation
658 // lines together. Clicking on this button (re)sets the curve
659 // mode for the three "current" keyframes simultanously, but
660 // never creates a new keyframe.
662 class CWindowCurveToggle : public BC_Toggle
665 CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
666 void check_toggle_state(FloatAuto *x, FloatAuto *y, FloatAuto *z);
675 CWindowCurveToggle::CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
676 : BC_Toggle(x, y, mwindow->theme->get_image_set(mode.icon_id), false),
680 this->mwindow = mwindow;
681 set_tooltip(_(cfg.tooltip));
684 void CWindowCurveToggle::check_toggle_state(FloatAuto *x, FloatAuto *y, FloatAuto *z)
686 // the toggle state is only set to ON if all
687 // three automation lines have the same curve mode.
688 // For mixed states the toggle stays off.
689 set_value( x->curve_mode == this->cfg.mode &&
690 y->curve_mode == this->cfg.mode &&
691 z->curve_mode == this->cfg.mode
692 ,true // redraw to show new state
696 int CWindowCurveToggle::handle_event()
698 Track *track = mwindow->cwindow->calculate_affected_track();
700 FloatAuto *x=0, *y=0, *z=0;
701 mwindow->cwindow->calculate_affected_autos(track,
702 &x, &y, &z, cfg.use_camera, 0,0,0); // don't create new keyframe
703 if( x ) x->change_curve_mode(cfg.mode);
704 if( y ) y->change_curve_mode(cfg.mode);
705 if( z ) z->change_curve_mode(cfg.mode);
708 gui->update_preview();
715 CWindowEyedropCheckBox::CWindowEyedropCheckBox(MWindow *mwindow,
716 CWindowEyedropGUI *gui, int x, int y)
717 : BC_CheckBox(x, y, mwindow->edl->local_session->use_max, _("Use maximum"))
719 this->mwindow = mwindow;
723 int CWindowEyedropCheckBox::handle_event()
725 mwindow->edl->local_session->use_max = get_value();
732 CWindowCameraGUI::CWindowCameraGUI(MWindow *mwindow, CWindowTool *thread)
733 : CWindowToolGUI(mwindow,
735 _(PROGRAM_NAME ": Camera"),
740 CWindowCameraGUI::~CWindowCameraGUI()
744 void CWindowCameraGUI::create_objects()
746 int x = 10, y = 10, x1;
747 Track *track = mwindow->cwindow->calculate_affected_track();
748 FloatAuto *x_auto = 0, *y_auto = 0, *z_auto = 0;
752 lock_window("CWindowCameraGUI::create_objects");
754 mwindow->cwindow->calculate_affected_autos(track,
755 &x_auto, &y_auto, &z_auto, 1, 0, 0, 0);
758 add_subwindow(title = new BC_Title(x, y, "X:"));
760 this->x = new CWindowCoord(this, x, y,
761 x_auto ? x_auto->get_value() : (float)0);
762 this->x->create_objects();
767 add_subwindow(title = new BC_Title(x, y, "Y:"));
769 this->y = new CWindowCoord(this, x, y,
770 y_auto ? y_auto->get_value() : (float)0);
771 this->y->create_objects();
774 add_subwindow(title = new BC_Title(x, y, "Z:"));
776 this->z = new CWindowCoord(this, x, y,
777 z_auto ? z_auto->get_value() : (float)1);
778 this->z->create_objects();
779 this->z->set_increment(0.01);
783 add_subwindow(button = new CWindowCameraLeft(mwindow, this, x1, y));
784 x1 += button->get_w();
785 add_subwindow(button = new CWindowCameraCenter(mwindow, this, x1, y));
786 x1 += button->get_w();
787 add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
789 y += button->get_h();
791 add_subwindow(button = new CWindowCameraTop(mwindow, this, x1, y));
792 x1 += button->get_w();
793 add_subwindow(button = new CWindowCameraMiddle(mwindow, this, x1, y));
794 x1 += button->get_w();
795 add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
796 // additional Buttons to control the curve mode of the "current" keyframe
797 x1 += button->get_w() + 15;
798 add_subwindow(this->t_smooth = new CWindowCurveToggle(Camera_Crv_Smooth, mwindow, this, x1, y));
799 x1 += button->get_w();
800 add_subwindow(this->t_linear = new CWindowCurveToggle(Camera_Crv_Linear, mwindow, this, x1, y));
802 // fill in current auto keyframe values, set toggle states.
807 void CWindowCameraGUI::update_preview()
809 CWindowGUI *cgui = mwindow->cwindow->gui;
810 cgui->lock_window("CWindowCameraGUI::update_preview");
811 cgui->sync_parameters(CHANGE_PARAMS, 0, 1);
812 cgui->unlock_window();
816 void CWindowCameraGUI::handle_event()
818 FloatAuto *x_auto = 0;
819 FloatAuto *y_auto = 0;
820 FloatAuto *z_auto = 0;
821 Track *track = mwindow->cwindow->calculate_affected_track();
824 mwindow->undo->update_undo_before(_("camera"), this);
825 if(event_caller == x)
827 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
828 track->automation->autos[AUTOMATION_CAMERA_X],
832 x_auto->set_value(atof(x->get_text()));
838 if(event_caller == y)
840 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
841 track->automation->autos[AUTOMATION_CAMERA_Y],
845 y_auto->set_value(atof(y->get_text()));
851 if(event_caller == z)
853 z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
854 track->automation->autos[AUTOMATION_CAMERA_Z],
858 float zoom = atof(z->get_text());
859 if(zoom > 100.) zoom = 100.;
861 if(zoom < 0.01) zoom = 0.01;
862 // Doesn't allow user to enter from scratch
863 // if(zoom != atof(z->get_text()))
866 z_auto->set_value(zoom);
867 mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
868 mwindow->gui->draw_overlays(1);
869 mwindow->gui->unlock_window();
875 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
879 void CWindowCameraGUI::update()
881 FloatAuto *x_auto = 0;
882 FloatAuto *y_auto = 0;
883 FloatAuto *z_auto = 0;
884 Track *track = mwindow->cwindow->calculate_affected_track();
886 mwindow->cwindow->calculate_affected_autos(track,
887 &x_auto, &y_auto, &z_auto, 1, 0, 0, 0);
891 x->update(x_auto->get_value());
893 y->update(y_auto->get_value());
895 float value = z_auto->get_value();
897 thread->gui->lock_window("CWindowCameraGUI::update");
898 thread->gui->composite_panel->cpanel_zoom->update(value);
899 thread->gui->unlock_window();
902 if( x_auto && y_auto && z_auto )
904 t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
905 t_linear->check_toggle_state(x_auto, y_auto, z_auto);
912 CWindowCameraLeft::CWindowCameraLeft(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
913 : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
916 this->mwindow = mwindow;
917 set_tooltip(_("Left justify"));
919 int CWindowCameraLeft::handle_event()
921 FloatAuto *x_auto = 0;
922 FloatAuto *z_auto = 0;
923 Track *track = mwindow->cwindow->calculate_affected_track();
925 mwindow->cwindow->calculate_affected_autos(track,
926 &x_auto, 0, &z_auto, 1, 1, 0, 0);
932 track->get_source_dimensions(
933 mwindow->edl->local_session->get_selectionstart(1),
939 mwindow->undo->update_undo_before(_("camera"), 0);
941 (double)track->track_w / z_auto->get_value() / 2 -
943 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
945 gui->update_preview();
953 CWindowCameraCenter::CWindowCameraCenter(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
954 : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
957 this->mwindow = mwindow;
958 set_tooltip(_("Center horizontal"));
960 int CWindowCameraCenter::handle_event()
962 FloatAuto *x_auto = 0;
963 Track *track = mwindow->cwindow->calculate_affected_track();
965 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
966 track->automation->autos[AUTOMATION_CAMERA_X],
971 mwindow->undo->update_undo_before(_("camera"), 0);
972 x_auto->set_value(0);
974 gui->update_preview();
975 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
982 CWindowCameraRight::CWindowCameraRight(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
983 : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
986 this->mwindow = mwindow;
987 set_tooltip(_("Right justify"));
989 int CWindowCameraRight::handle_event()
991 FloatAuto *x_auto = 0;
992 FloatAuto *z_auto = 0;
993 Track *track = mwindow->cwindow->calculate_affected_track();
995 mwindow->cwindow->calculate_affected_autos(track,
996 &x_auto, 0, &z_auto, 1, 1, 0, 0);
1002 track->get_source_dimensions(
1003 mwindow->edl->local_session->get_selectionstart(1),
1009 mwindow->undo->update_undo_before(_("camera"), 0);
1010 x_auto->set_value( -((double)track->track_w / z_auto->get_value() / 2 -
1013 gui->update_preview();
1014 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1022 CWindowCameraTop::CWindowCameraTop(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1023 : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1026 this->mwindow = mwindow;
1027 set_tooltip(_("Top justify"));
1029 int CWindowCameraTop::handle_event()
1031 FloatAuto *y_auto = 0;
1032 FloatAuto *z_auto = 0;
1033 Track *track = mwindow->cwindow->calculate_affected_track();
1035 mwindow->cwindow->calculate_affected_autos(track,
1036 0, &y_auto, &z_auto, 1, 0, 1, 0);
1039 if(y_auto && z_auto)
1042 track->get_source_dimensions(
1043 mwindow->edl->local_session->get_selectionstart(1),
1049 mwindow->undo->update_undo_before(_("camera"), 0);
1050 y_auto->set_value((double)track->track_h / z_auto->get_value() / 2 -
1053 gui->update_preview();
1054 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1062 CWindowCameraMiddle::CWindowCameraMiddle(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1063 : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1066 this->mwindow = mwindow;
1067 set_tooltip(_("Center vertical"));
1069 int CWindowCameraMiddle::handle_event()
1071 FloatAuto *y_auto = 0;
1072 Track *track = mwindow->cwindow->calculate_affected_track();
1074 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1075 track->automation->autos[AUTOMATION_CAMERA_Y], 1);
1079 mwindow->undo->update_undo_before(_("camera"), 0);
1080 y_auto->set_value(0);
1082 gui->update_preview();
1083 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1090 CWindowCameraBottom::CWindowCameraBottom(MWindow *mwindow, CWindowCameraGUI *gui, int x, int y)
1091 : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1094 this->mwindow = mwindow;
1095 set_tooltip(_("Bottom justify"));
1097 int CWindowCameraBottom::handle_event()
1099 FloatAuto *y_auto = 0;
1100 FloatAuto *z_auto = 0;
1101 Track *track = mwindow->cwindow->calculate_affected_track();
1103 mwindow->cwindow->calculate_affected_autos(track,
1104 0, &y_auto, &z_auto, 1, 0, 1, 0);
1107 if(y_auto && z_auto)
1110 track->get_source_dimensions(
1111 mwindow->edl->local_session->get_selectionstart(1),
1117 mwindow->undo->update_undo_before(_("camera"), 0);
1118 y_auto->set_value(-((double)track->track_h / z_auto->get_value() / 2 -
1121 gui->update_preview();
1122 mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
1130 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
1131 : CWindowToolGUI(mwindow,
1133 _(PROGRAM_NAME ": Projector"),
1138 CWindowProjectorGUI::~CWindowProjectorGUI()
1141 void CWindowProjectorGUI::create_objects()
1143 int x = 10, y = 10, x1;
1144 Track *track = mwindow->cwindow->calculate_affected_track();
1145 FloatAuto *x_auto = 0;
1146 FloatAuto *y_auto = 0;
1147 FloatAuto *z_auto = 0;
1151 lock_window("CWindowProjectorGUI::create_objects");
1153 mwindow->cwindow->calculate_affected_autos(track,
1154 &x_auto, &y_auto, &z_auto, 0, 0, 0, 0);
1157 add_subwindow(title = new BC_Title(x, y, "X:"));
1158 x += title->get_w();
1159 this->x = new CWindowCoord(this, x, y,
1160 x_auto ? x_auto->get_value() : (float)0);
1161 this->x->create_objects();
1164 add_subwindow(title = new BC_Title(x, y, "Y:"));
1165 x += title->get_w();
1166 this->y = new CWindowCoord(this, x, y,
1167 y_auto ? y_auto->get_value() : (float)0);
1168 this->y->create_objects();
1171 add_subwindow(title = new BC_Title(x, y, "Z:"));
1172 x += title->get_w();
1173 this->z = new CWindowCoord(this, x, y,
1174 z_auto ? z_auto->get_value() : (float)1);
1175 this->z->create_objects();
1176 this->z->set_increment(0.01);
1180 add_subwindow(button = new CWindowProjectorLeft(mwindow, this, x1, y));
1181 x1 += button->get_w();
1182 add_subwindow(button = new CWindowProjectorCenter(mwindow, this, x1, y));
1183 x1 += button->get_w();
1184 add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
1186 y += button->get_h();
1188 add_subwindow(button = new CWindowProjectorTop(mwindow, this, x1, y));
1189 x1 += button->get_w();
1190 add_subwindow(button = new CWindowProjectorMiddle(mwindow, this, x1, y));
1191 x1 += button->get_w();
1192 add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
1194 // additional Buttons to control the curve mode of the "current" keyframe
1195 x1 += button->get_w() + 15;
1196 add_subwindow(this->t_smooth = new CWindowCurveToggle(Projector_Crv_Smooth, mwindow, this, x1, y));
1197 x1 += button->get_w();
1198 add_subwindow(this->t_linear = new CWindowCurveToggle(Projector_Crv_Linear, mwindow, this, x1, y));
1200 // fill in current auto keyframe values, set toggle states.
1205 void CWindowProjectorGUI::update_preview()
1207 CWindowGUI *cgui = mwindow->cwindow->gui;
1208 cgui->lock_window("CWindowProjectorGUI::update_preview");
1209 cgui->sync_parameters(CHANGE_PARAMS, 0, 1);
1210 cgui->unlock_window();
1213 void CWindowProjectorGUI::handle_event()
1215 FloatAuto *x_auto = 0;
1216 FloatAuto *y_auto = 0;
1217 FloatAuto *z_auto = 0;
1218 Track *track = mwindow->cwindow->calculate_affected_track();
1222 mwindow->undo->update_undo_before(_("projector"), this);
1223 if(event_caller == x)
1225 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1226 track->automation->autos[AUTOMATION_PROJECTOR_X],
1230 x_auto->set_value(atof(x->get_text()));
1236 if(event_caller == y)
1238 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1239 track->automation->autos[AUTOMATION_PROJECTOR_Y],
1243 y_auto->set_value(atof(y->get_text()));
1249 if(event_caller == z)
1251 z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1252 track->automation->autos[AUTOMATION_PROJECTOR_Z],
1256 float zoom = atof(z->get_text());
1257 if(zoom > 100.) zoom = 100.;
1258 else if(zoom < 0.01) zoom = 0.01;
1259 // if (zoom != atof(z->get_text()))
1261 z_auto->set_value(zoom);
1263 mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
1264 mwindow->gui->draw_overlays(1);
1265 mwindow->gui->unlock_window();
1271 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1275 void CWindowProjectorGUI::update()
1277 FloatAuto *x_auto = 0;
1278 FloatAuto *y_auto = 0;
1279 FloatAuto *z_auto = 0;
1280 Track *track = mwindow->cwindow->calculate_affected_track();
1282 mwindow->cwindow->calculate_affected_autos(track,
1283 &x_auto, &y_auto, &z_auto, 0, 0, 0, 0);
1287 x->update(x_auto->get_value());
1289 y->update(y_auto->get_value());
1291 float value = z_auto->get_value();
1293 thread->gui->lock_window("CWindowProjectorGUI::update");
1294 thread->gui->composite_panel->cpanel_zoom->update(value);
1295 thread->gui->unlock_window();
1298 if( x_auto && y_auto && z_auto )
1300 t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
1301 t_linear->check_toggle_state(x_auto, y_auto, z_auto);
1305 CWindowProjectorLeft::CWindowProjectorLeft(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1306 : BC_Button(x, y, mwindow->theme->get_image_set("left_justify"))
1309 this->mwindow = mwindow;
1310 set_tooltip(_("Left justify"));
1312 int CWindowProjectorLeft::handle_event()
1314 FloatAuto *x_auto = 0;
1315 FloatAuto *z_auto = 0;
1316 Track *track = mwindow->cwindow->calculate_affected_track();
1318 mwindow->cwindow->calculate_affected_autos(track,
1319 &x_auto, 0, &z_auto, 0, 1, 0, 0);
1321 if(x_auto && z_auto)
1323 mwindow->undo->update_undo_before(_("projector"), 0);
1324 x_auto->set_value( (double)track->track_w * z_auto->get_value() / 2 -
1325 (double)mwindow->edl->session->output_w / 2 );
1327 gui->update_preview();
1328 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1335 CWindowProjectorCenter::CWindowProjectorCenter(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1336 : BC_Button(x, y, mwindow->theme->get_image_set("center_justify"))
1339 this->mwindow = mwindow;
1340 set_tooltip(_("Center horizontal"));
1342 int CWindowProjectorCenter::handle_event()
1344 FloatAuto *x_auto = 0;
1345 Track *track = mwindow->cwindow->calculate_affected_track();
1347 x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1348 track->automation->autos[AUTOMATION_PROJECTOR_X],
1353 mwindow->undo->update_undo_before(_("projector"), 0);
1354 x_auto->set_value(0);
1356 gui->update_preview();
1357 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1364 CWindowProjectorRight::CWindowProjectorRight(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1365 : BC_Button(x, y, mwindow->theme->get_image_set("right_justify"))
1368 this->mwindow = mwindow;
1369 set_tooltip(_("Right justify"));
1371 int CWindowProjectorRight::handle_event()
1373 FloatAuto *x_auto = 0;
1374 FloatAuto *z_auto = 0;
1375 Track *track = mwindow->cwindow->calculate_affected_track();
1377 mwindow->cwindow->calculate_affected_autos(track,
1378 &x_auto, 0, &z_auto, 0, 1, 0, 0);
1381 if(x_auto && z_auto)
1383 mwindow->undo->update_undo_before(_("projector"), 0);
1384 x_auto->set_value( -((double)track->track_w * z_auto->get_value() / 2 -
1385 (double)mwindow->edl->session->output_w / 2));
1387 gui->update_preview();
1388 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1395 CWindowProjectorTop::CWindowProjectorTop(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1396 : BC_Button(x, y, mwindow->theme->get_image_set("top_justify"))
1399 this->mwindow = mwindow;
1400 set_tooltip(_("Top justify"));
1402 int CWindowProjectorTop::handle_event()
1404 FloatAuto *y_auto = 0;
1405 FloatAuto *z_auto = 0;
1406 Track *track = mwindow->cwindow->calculate_affected_track();
1408 mwindow->cwindow->calculate_affected_autos(track,
1409 0, &y_auto, &z_auto, 0, 0, 1, 0);
1412 if(y_auto && z_auto)
1414 mwindow->undo->update_undo_before(_("projector"), 0);
1415 y_auto->set_value( (double)track->track_h * z_auto->get_value() / 2 -
1416 (double)mwindow->edl->session->output_h / 2 );
1418 gui->update_preview();
1419 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1426 CWindowProjectorMiddle::CWindowProjectorMiddle(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1427 : BC_Button(x, y, mwindow->theme->get_image_set("middle_justify"))
1430 this->mwindow = mwindow;
1431 set_tooltip(_("Center vertical"));
1433 int CWindowProjectorMiddle::handle_event()
1435 FloatAuto *y_auto = 0;
1436 Track *track = mwindow->cwindow->calculate_affected_track();
1438 y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
1439 track->automation->autos[AUTOMATION_PROJECTOR_Y], 1);
1443 mwindow->undo->update_undo_before(_("projector"), 0);
1444 y_auto->set_value(0);
1446 gui->update_preview();
1447 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1454 CWindowProjectorBottom::CWindowProjectorBottom(MWindow *mwindow, CWindowProjectorGUI *gui, int x, int y)
1455 : BC_Button(x, y, mwindow->theme->get_image_set("bottom_justify"))
1458 this->mwindow = mwindow;
1459 set_tooltip(_("Bottom justify"));
1461 int CWindowProjectorBottom::handle_event()
1463 FloatAuto *y_auto = 0;
1464 FloatAuto *z_auto = 0;
1465 Track *track = mwindow->cwindow->calculate_affected_track();
1467 mwindow->cwindow->calculate_affected_autos(track,
1468 0, &y_auto, &z_auto, 0, 0, 1, 0);
1471 if(y_auto && z_auto)
1473 mwindow->undo->update_undo_before(_("projector"), 0);
1474 y_auto->set_value( -((double)track->track_h * z_auto->get_value() / 2 -
1475 (double)mwindow->edl->session->output_h / 2));
1477 gui->update_preview();
1478 mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
1485 CWindowMaskTrack::CWindowMaskTrack(MWindow *mwindow, CWindowMaskGUI *gui,
1486 int x, int y, const char *text)
1487 : BC_Title(x, y, text, MEDIUMFONT, get_resources()->button_highlighted)
1489 this->mwindow = mwindow;
1493 CWindowMaskTrack::~CWindowMaskTrack()
1497 CWindowMaskName::CWindowMaskName(MWindow *mwindow, CWindowMaskGUI *gui,
1498 int x, int y, const char *text)
1499 : BC_PopupTextBox(gui, 0, text, x, y, 100, 160)
1501 this->mwindow = mwindow;
1505 CWindowMaskName::~CWindowMaskName()
1509 int CWindowMaskName::handle_event()
1516 //printf("CWindowMaskGUI::update 1\n");
1517 gui->get_keyframe(track, autos, keyframe, mask, point, 0);
1519 int k = get_number();
1520 if( k < 0 ) k = mwindow->edl->session->cwindow_mask;
1521 else mwindow->edl->session->cwindow_mask = k;
1522 if( k >= 0 && k < mask_items.size() ) {
1523 mask_items[k]->set_text(get_text());
1524 update_list(&mask_items);
1526 #ifdef USE_KEYFRAME_SPANNING
1527 MaskAuto temp_keyframe(mwindow->edl, autos);
1528 temp_keyframe.copy_data(keyframe);
1529 SubMask *submask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
1530 memset(submask->name, 0, sizeof(submask->name));
1531 strncpy(submask->name, get_text(), sizeof(submask->name)-1);
1532 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->update_parameter(&temp_keyframe);
1534 for(MaskAuto *current = (MaskAuto*)autos->default_auto; current; ) {
1535 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1536 memset(submask->name, 0, sizeof(submask->name));
1537 strncpy(submask->name, get_text(), sizeof(submask->name));
1538 current = current == (MaskAuto*)autos->default_auto ?
1539 (MaskAuto*)autos->first : (MaskAuto*)NEXT;
1543 gui->update_preview();
1548 void CWindowMaskName::update_items(MaskAuto *keyframe)
1550 mask_items.remove_all_objects();
1551 int sz = !keyframe ? 0 : keyframe->masks.size();
1552 for( int i=0; i<SUBMASKS; ++i ) {
1553 char text[BCSTRLEN];
1555 SubMask *sub_mask = keyframe->masks.get(i);
1556 strncpy(text, sub_mask->name, sizeof(text));
1559 sprintf(text, "%d", i);
1560 mask_items.append(new BC_ListBoxItem(text));
1562 update_list(&mask_items);
1566 CWindowMaskButton::CWindowMaskButton(MWindow *mwindow, CWindowMaskGUI *gui,
1567 int x, int y, int no, int v)
1568 : BC_CheckBox(x, y, v)
1570 this->mwindow = mwindow;
1575 CWindowMaskButton::~CWindowMaskButton()
1579 int CWindowMaskButton::handle_event()
1581 mwindow->edl->session->cwindow_mask = no;
1582 gui->name->update(gui->name->mask_items[no]->get_text());
1584 gui->update_preview();
1588 CWindowMaskThumbler::CWindowMaskThumbler(MWindow *mwindow, CWindowMaskGUI *gui,
1592 this->mwindow = mwindow;
1596 CWindowMaskThumbler::~CWindowMaskThumbler()
1600 int CWindowMaskThumbler::handle_up_event()
1605 int CWindowMaskThumbler::handle_down_event()
1607 return do_event(-1);
1610 int CWindowMaskThumbler::do_event(int dir)
1612 int k = mwindow->edl->session->cwindow_mask;
1613 if( (k+=dir) >= SUBMASKS ) k = 0;
1614 else if( k < 0 ) k = SUBMASKS-1;
1615 mwindow->edl->session->cwindow_mask = k;
1616 gui->name->update(gui->name->mask_items[k]->get_text());
1618 gui->update_preview();
1623 CWindowMaskDelMask::CWindowMaskDelMask(MWindow *mwindow,
1624 CWindowToolGUI *gui, int x, int y)
1625 : BC_GenericButton(x, y, _("Delete"))
1627 this->mwindow = mwindow;
1629 set_tooltip(_("Delete mask"));
1632 int CWindowMaskDelMask::handle_event()
1641 // Get existing keyframe
1642 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1645 mwindow->undo->update_undo_before(_("mask delete"), 0);
1647 #ifdef USE_KEYFRAME_SPANNING
1648 // Create temp keyframe
1649 MaskAuto temp_keyframe(mwindow->edl, autos);
1650 temp_keyframe.copy_data(keyframe);
1651 SubMask *submask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
1652 submask->points.remove_all_objects();
1654 // Commit change to span of keyframes
1655 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->update_parameter(&temp_keyframe);
1657 for(MaskAuto *current = (MaskAuto*)autos->default_auto; current; ) {
1658 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1659 submask->points.clear();
1660 current = current == (MaskAuto*)autos->default_auto ?
1661 (MaskAuto*)autos->first : (MaskAuto*)NEXT;
1665 if( mwindow->cwindow->gui->affected_point >= total_points )
1666 mwindow->cwindow->gui->affected_point =
1667 total_points > 0 ? total_points-1 : 0;
1670 gui->update_preview();
1671 mwindow->undo->update_undo_after(_("mask delete"), LOAD_AUTOMATION);
1677 CWindowMaskDelPoint::CWindowMaskDelPoint(MWindow *mwindow,
1678 CWindowToolGUI *gui, int x, int y)
1679 : BC_GenericButton(x, y, _("Delete"))
1681 this->mwindow = mwindow;
1683 set_tooltip(_("Delete point"));
1686 int CWindowMaskDelPoint::handle_event()
1695 // Get existing keyframe
1696 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
1698 mwindow->undo->update_undo_before(_("point delete"), 0);
1700 #ifdef USE_KEYFRAME_SPANNING
1701 // Create temp keyframe
1702 MaskAuto temp_keyframe(mwindow->edl, autos);
1703 temp_keyframe.copy_data(keyframe);
1705 SubMask *submask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
1706 int i = mwindow->cwindow->gui->affected_point;
1707 for( ; i<submask->points.total-1; ++i )
1708 *submask->points.values[i] = *submask->points.values[i+1];
1709 if( submask->points.total > 0 ) {
1710 point = submask->points.values[submask->points.total-1];
1711 submask->points.remove_object(point);
1713 total_points = submask->points.total;
1715 // Commit change to span of keyframes
1716 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->update_parameter(&temp_keyframe);
1718 MaskAuto *current = (MaskAuto*)autos->default_auto;
1720 SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
1721 int i = mwindow->cwindow->gui->affected_point;
1722 for( ; i<submask->points.total-1; ++i ) {
1723 *submask->points.values[i] = *submask->points.values[i+1];
1724 if( submask->points.total > 0 ) {
1725 point = submask->points.values[submask->points.total-1];
1726 submask->points.remove_object(point);
1728 total_points = submask->points.total;
1729 current = current == (MaskAuto*)autos->default_auto ?
1730 (MaskAuto*)autos->first : (MaskAuto*)NEXT;
1733 if( mwindow->cwindow->gui->affected_point >= total_points )
1734 mwindow->cwindow->gui->affected_point =
1735 total_points > 0 ? total_points-1 : 0;
1738 gui->update_preview();
1739 mwindow->undo->update_undo_after(_("mask delete"), LOAD_AUTOMATION);
1745 int CWindowMaskDelPoint::keypress_event()
1747 if( get_keypress() == BACKSPACE ||
1748 get_keypress() == DELETE )
1749 return handle_event();
1756 CWindowMaskAffectedPoint::CWindowMaskAffectedPoint(MWindow *mwindow,
1757 CWindowToolGUI *gui, int x, int y)
1758 : BC_TumbleTextBox(gui,
1759 (int64_t)mwindow->cwindow->gui->affected_point,
1760 (int64_t)0, INT64_MAX, x, y, 100)
1762 this->mwindow = mwindow;
1766 CWindowMaskAffectedPoint::~CWindowMaskAffectedPoint()
1770 int CWindowMaskAffectedPoint::handle_event()
1772 int total_points = 0;
1773 int affected_point = atol(get_text());
1774 Track *track = mwindow->cwindow->calculate_affected_track();
1776 MaskAutos *autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
1777 MaskAuto *keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(autos, 0);
1779 SubMask *mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
1780 total_points = mask->points.size();
1783 int active_point = affected_point;
1784 if( affected_point >= total_points )
1785 affected_point = total_points - 1;
1786 if( affected_point < 0 )
1788 if( active_point != affected_point )
1789 update((int64_t)affected_point);
1790 mwindow->cwindow->gui->affected_point = affected_point;
1792 gui->update_preview();
1797 CWindowMaskFocus::CWindowMaskFocus(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1798 : BC_CheckBox(x, y, ((CWindowMaskGUI*)gui)->focused, _("Focus"))
1800 this->mwindow = mwindow;
1802 set_tooltip(_("Center for rotate/scale"));
1805 CWindowMaskFocus::~CWindowMaskFocus()
1809 int CWindowMaskFocus::handle_event()
1811 ((CWindowMaskGUI*)gui)->focused = get_value();
1813 gui->update_preview();
1817 CWindowMaskDrawCenter::CWindowMaskDrawCenter(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1818 : BC_CheckBox(x, y, ((CWindowMaskGUI*)gui)->center_mark, _("Center Mark"))
1820 this->mwindow = mwindow;
1822 set_tooltip(_("show center of mask points"));
1825 CWindowMaskDrawCenter::~CWindowMaskDrawCenter()
1829 int CWindowMaskDrawCenter::handle_event()
1831 ((CWindowMaskGUI*)gui)->center_mark = get_value();
1833 gui->update_preview();
1837 CWindowMaskDrawMarkers::CWindowMaskDrawMarkers(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1838 : BC_CheckBox(x, y, ((CWindowMaskGUI*)gui)->markers, _("Markers"))
1840 this->mwindow = mwindow;
1842 set_tooltip("Display points");
1845 CWindowMaskDrawMarkers::~CWindowMaskDrawMarkers()
1849 int CWindowMaskDrawMarkers::handle_event()
1851 ((CWindowMaskGUI*)gui)->markers = get_value();
1853 gui->update_preview();
1857 CWindowMaskDrawBoundary::CWindowMaskDrawBoundary(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1858 : BC_CheckBox(x, y, ((CWindowMaskGUI*)gui)->boundary, _("Boundary"))
1860 this->mwindow = mwindow;
1862 set_tooltip("Display mask outline");
1865 CWindowMaskDrawBoundary::~CWindowMaskDrawBoundary()
1869 int CWindowMaskDrawBoundary::handle_event()
1871 ((CWindowMaskGUI*)gui)->boundary = get_value();
1873 gui->update_preview();
1878 CWindowMaskFeather::CWindowMaskFeather(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1879 : BC_TumbleTextBox(gui, 0, -FEATHER_MAX, FEATHER_MAX, x, y, 64, 2)
1881 this->mwindow = mwindow;
1884 CWindowMaskFeather::~CWindowMaskFeather()
1888 int CWindowMaskFeather::update(float v)
1890 CWindowMaskGUI *mask_gui = (CWindowMaskGUI*)gui;
1891 mask_gui->feather_slider->update(v);
1892 return BC_TumbleTextBox::update(v);
1895 int CWindowMaskFeather::update_value(float v)
1902 #ifdef USE_KEYFRAME_SPANNING
1908 mwindow->undo->update_undo_before(_("mask feather"), this);
1910 // Get existing keyframe
1911 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe,
1912 mask, point, create_it);
1914 int gang = ((CWindowMaskGUI*)gui)->gang_feather->get_value();
1915 #ifdef USE_KEYFRAME_SPANNING
1916 MaskAuto temp_keyframe(mwindow->edl, autos);
1917 temp_keyframe.copy_data(keyframe);
1918 keyframe = &temp_keyframe;
1920 float change = v - mask->feather;
1921 int k = mwindow->edl->session->cwindow_mask;
1922 int n = gang ? keyframe->masks.size() : k+1;
1923 for( int i=gang? 0 : k; i<n; ++i ) {
1924 SubMask *sub_mask = keyframe->get_submask(i);
1925 float feather = sub_mask->feather + change;
1926 bclamp(feather, -FEATHER_MAX, FEATHER_MAX);
1927 sub_mask->feather = feather;
1929 #ifdef USE_KEYFRAME_SPANNING
1930 autos->update_parameter(keyframe);
1932 gui->update_preview();
1935 mwindow->undo->update_undo_after(_("mask feather"), LOAD_AUTOMATION);
1939 int CWindowMaskFeather::handle_event()
1941 float v = atof(get_text());
1942 CWindowMaskGUI * mask_gui = (CWindowMaskGUI*)gui;
1943 mask_gui->feather_slider->update(v);
1944 return mask_gui->feather->update_value(v);
1947 CWindowMaskFeatherSlider::CWindowMaskFeatherSlider(MWindow *mwindow,
1948 CWindowToolGUI *gui, int x, int y, int w, float v)
1949 : BC_FSlider(x, y, 0, w, w, -FEATHER_MAX, FEATHER_MAX, v)
1951 this->mwindow = mwindow;
1953 set_precision(0.01);
1954 timer = new Timer();
1959 CWindowMaskFeatherSlider::~CWindowMaskFeatherSlider()
1964 int CWindowMaskFeatherSlider::handle_event()
1966 float v = get_value();
1968 int64_t ms = timer->get_difference();
1969 if( ms < 250 && --stick > 0 ) {
1970 if( get_value() == 0 ) return 1;
1978 else if( (last_v>=0 && v<0) || (last_v<0 && v>=0) ) {
1985 CWindowMaskGUI * mask_gui = (CWindowMaskGUI*)gui;
1986 mask_gui->feather->BC_TumbleTextBox::update(v);
1987 return mask_gui->feather->update_value(v);
1990 int CWindowMaskFeatherSlider::update(float v)
1992 return BC_FSlider::update(v);
1995 CWindowMaskFade::CWindowMaskFade(MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
1996 : BC_TumbleTextBox(gui, 0, -100.f, 100.f, x, y, 64, 2)
1998 this->mwindow = mwindow;
2001 CWindowMaskFade::~CWindowMaskFade()
2005 int CWindowMaskFade::update(float v)
2007 CWindowMaskGUI *mask_gui = (CWindowMaskGUI*)gui;
2008 mask_gui->fade_slider->update(v);
2009 return BC_TumbleTextBox::update(v);
2012 int CWindowMaskFade::update_value(float v)
2019 #ifdef USE_KEYFRAME_SPANNING
2025 mwindow->undo->update_undo_before(_("mask fade"), this);
2027 // Get existing keyframe
2028 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe,
2029 mask, point, create_it);
2031 int gang = ((CWindowMaskGUI*)gui)->gang_fader->get_value();
2032 #ifdef USE_KEYFRAME_SPANNING
2033 MaskAuto temp_keyframe(mwindow->edl, autos);
2034 temp_keyframe.copy_data(keyframe);
2035 keyframe = &temp_keyframe;
2037 float change = v - mask->fader;
2038 int k = mwindow->edl->session->cwindow_mask;
2039 int n = gang ? keyframe->masks.size() : k+1;
2040 for( int i=gang? 0 : k; i<n; ++i ) {
2041 SubMask *sub_mask = keyframe->get_submask(i);
2042 float fader = sub_mask->fader + change;
2043 bclamp(fader, -100.f, 100.f);
2044 sub_mask->fader = fader;
2046 #ifdef USE_KEYFRAME_SPANNING
2047 autos->update_parameter(keyframe);
2049 gui->update_preview();
2052 mwindow->undo->update_undo_after(_("mask fade"), LOAD_AUTOMATION);
2056 int CWindowMaskFade::handle_event()
2058 float v = atof(get_text());
2059 CWindowMaskGUI * mask_gui = (CWindowMaskGUI*)gui;
2060 mask_gui->fade_slider->update(v);
2061 return mask_gui->fade->update_value(v);
2064 CWindowMaskFadeSlider::CWindowMaskFadeSlider(MWindow *mwindow, CWindowToolGUI *gui,
2065 int x, int y, int w)
2066 : BC_ISlider(x, y, 0, w, w, -200, 200, 0)
2068 this->mwindow = mwindow;
2070 timer = new Timer();
2075 CWindowMaskFadeSlider::~CWindowMaskFadeSlider()
2080 int CWindowMaskFadeSlider::handle_event()
2082 float v = 100*get_value()/200;
2084 int64_t ms = timer->get_difference();
2085 if( ms < 250 && --stick > 0 ) {
2086 if( get_value() == 0 ) return 1;
2094 else if( (last_v>=0 && v<0) || (last_v<0 && v>=0) ) {
2101 CWindowMaskGUI *mask_gui = (CWindowMaskGUI*)gui;
2102 mask_gui->fade->BC_TumbleTextBox::update(v);
2103 return mask_gui->fade->update_value(v);
2106 int CWindowMaskFadeSlider::update(int64_t v)
2108 return BC_ISlider::update(200*v/100);
2111 CWindowMaskGangFader::CWindowMaskGangFader(MWindow *mwindow,
2112 CWindowToolGUI *gui, int x, int y)
2113 : BC_Toggle(x, y, mwindow->theme->get_image_set("gangpatch_data"), 0)
2115 this->mwindow = mwindow;
2117 set_tooltip(_("Gang fader"));
2120 CWindowMaskGangFader::~CWindowMaskGangFader()
2124 int CWindowMaskGangFader::handle_event()
2129 CWindowMaskBeforePlugins::CWindowMaskBeforePlugins(CWindowToolGUI *gui, int x, int y)
2133 _("Apply mask before plugins"))
2138 int CWindowMaskBeforePlugins::handle_event()
2145 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 1);
2148 int v = get_value();
2149 #ifdef USE_KEYFRAME_SPANNING
2150 MaskAuto temp_keyframe(gui->mwindow->edl, autos);
2151 temp_keyframe.copy_data(keyframe);
2152 temp_keyframe.apply_before_plugins = v;
2153 autos->update_parameter(&temp_keyframe);
2155 keyframe->apply_before_plugins = v;
2157 gui->update_preview();
2163 CWindowDisableOpenGLMasking::CWindowDisableOpenGLMasking(CWindowToolGUI *gui, int x, int y)
2164 : BC_CheckBox(x, y, 1, _("Disable OpenGL masking"))
2169 int CWindowDisableOpenGLMasking::handle_event()
2176 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 1);
2179 int v = get_value();
2180 #ifdef USE_KEYFRAME_SPANNING
2181 MaskAuto temp_keyframe(gui->mwindow->edl, autos);
2182 temp_keyframe.copy_data(keyframe);
2183 temp_keyframe.disable_opengl_masking = v;
2184 autos->update_parameter(&temp_keyframe);
2186 keyframe->disable_opengl_masking = v;
2188 gui->update_preview();
2194 CWindowMaskClrMask::CWindowMaskClrMask(MWindow *mwindow,
2195 CWindowMaskGUI *gui, int x, int y)
2196 : BC_Button(x, y, mwindow->theme->get_image_set("reset_button"))
2198 this->mwindow = mwindow;
2200 set_tooltip(_("Delete all masks"));
2203 CWindowMaskClrMask::~CWindowMaskClrMask()
2207 int CWindowMaskClrMask::calculate_w(MWindow *mwindow)
2209 VFrame *vfrm = *mwindow->theme->get_image_set("reset_button");
2210 return vfrm->get_w();
2213 int CWindowMaskClrMask::handle_event()
2221 // Get existing keyframe
2222 ((CWindowMaskGUI*)gui)->get_keyframe(track, autos, keyframe, mask, point, 0);
2225 mwindow->undo->update_undo_before(_("del masks"), 0);
2226 ((MaskAutos*)track->automation->autos[AUTOMATION_MASK])->clear_all();
2228 gui->update_preview();
2229 mwindow->undo->update_undo_after(_("del masks"), LOAD_AUTOMATION);
2235 CWindowMaskGangFeather::CWindowMaskGangFeather(MWindow *mwindow,
2236 CWindowToolGUI *gui, int x, int y)
2237 : BC_Toggle(x, y, mwindow->theme->get_image_set("gangpatch_data"), 0)
2239 this->mwindow = mwindow;
2241 set_tooltip(_("Gang feather"));
2244 CWindowMaskGangFeather::~CWindowMaskGangFeather()
2248 int CWindowMaskGangFeather::handle_event()
2253 CWindowMaskGUI::CWindowMaskGUI(MWindow *mwindow, CWindowTool *thread)
2254 : CWindowToolGUI(mwindow, thread,
2255 _(PROGRAM_NAME ": Mask"), 360, 620)
2257 this->mwindow = mwindow;
2258 this->thread = thread;
2267 CWindowMaskGUI::~CWindowMaskGUI()
2269 lock_window("CWindowMaskGUI::~CWindowMaskGUI");
2270 delete active_point;
2276 void CWindowMaskGUI::create_objects()
2278 int x = 10, y = 10, margin = mwindow->theme->widget_border;
2279 int clr_x = get_w()-x - CWindowMaskClrMask::calculate_w(mwindow);
2280 int del_x = clr_x-margin - CWindowMaskDelMask::calculate_w(this,_("Delete"));
2281 //MaskAuto *keyframe = 0;
2282 //Track *track = mwindow->cwindow->calculate_affected_track();
2284 // keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(track->automation->autos[AUTOMATION_MASK], 0);
2286 lock_window("CWindowMaskGUI::create_objects");
2287 BC_TitleBar *title_bar;
2288 add_subwindow(title_bar = new BC_TitleBar(x, y, get_w()-2*x, 20, 10, _("Masks on Track")));
2289 y += title_bar->get_h() + margin;
2291 add_subwindow(mask_track = new CWindowMaskTrack(mwindow, this, x1, y, ""));
2292 y += mask_track->get_h() + margin;
2293 add_subwindow(title_bar = new BC_TitleBar(x, y, get_w()-2*x, 20, 10, _("Masks")));
2294 y += title_bar->get_h() + margin;
2296 add_subwindow(title = new BC_Title(x, y, _("Mask:")));
2297 name = new CWindowMaskName(mwindow, this, x1, y, "");
2298 name->create_objects();
2299 add_subwindow(clr_mask = new CWindowMaskClrMask(mwindow, this, clr_x, y));
2300 add_subwindow(del_mask = new CWindowMaskDelMask(mwindow, this, del_x, y));
2301 y += name->get_h() + margin;
2304 BC_CheckBox::calculate_extents(this, &bw, &bh);
2305 int bdx = bw + margin;
2307 for( int i=0; i<SUBMASKS; x2+=bdx, ++i ) {
2308 int v = i == mwindow->edl->session->cwindow_mask ? 1 : 0;
2309 mask_buttons[i] = new CWindowMaskButton(mwindow, this, x2, y, i, v);
2310 add_subwindow(mask_buttons[i]);
2313 add_subwindow(mask_thumbler = new CWindowMaskThumbler(mwindow, this, x2, y));
2316 for( int i=0; i<SUBMASKS; x2+=bdx, ++i ) {
2317 char text[BCSTRLEN]; sprintf(text, "%d", i);
2318 int tx = (bw - get_text_width(MEDIUMFONT, text)) / 2;
2319 mask_blabels[i] = new BC_Title(x2+tx, y, text);
2320 add_subwindow(mask_blabels[i]);
2322 y += mask_blabels[0]->get_h() + 2*margin;
2323 add_subwindow(title_bar = new BC_TitleBar(x, y, get_w()-2*x, 20, 10, _("Fade & Feather")));
2324 y += title_bar->get_h() + margin;
2326 add_subwindow(title = new BC_Title(x, y, _("Fade:")));
2327 fade = new CWindowMaskFade(mwindow, this, x1, y);
2328 fade->create_objects();
2329 x2 = x1 + fade->get_w() + 2*margin;
2330 int w2 = clr_x-2*margin - x2;
2331 add_subwindow(fade_slider = new CWindowMaskFadeSlider(mwindow, this, x2, y, w2));
2332 add_subwindow(gang_fader = new CWindowMaskGangFader(mwindow, this, clr_x, y));
2333 y += fade->get_h() + margin;
2334 add_subwindow(title = new BC_Title(x, y, _("Feather:")));
2335 feather = new CWindowMaskFeather(mwindow, this, x1, y);
2336 feather->create_objects();
2337 w2 = clr_x - 2*margin - x2;
2338 feather_slider = new CWindowMaskFeatherSlider(mwindow, this, x2, y, w2, 0);
2339 add_subwindow(feather_slider);
2340 add_subwindow(gang_feather = new CWindowMaskGangFeather(mwindow, this, clr_x, y));
2341 y += feather->get_h() + 2*margin;
2342 add_subwindow(title_bar = new BC_TitleBar(x, y, get_w()-2*x, 20, 10, _("Mask Points")));
2343 y += title_bar->get_h() + margin;
2345 add_subwindow(title = new BC_Title(x, y, _("Point:")));
2346 active_point = new CWindowMaskAffectedPoint(mwindow, this, x1, y);
2347 active_point->create_objects();
2348 add_subwindow(del_point = new CWindowMaskDelPoint(mwindow, this, del_x, y));
2349 y += active_point->get_h() + margin;
2350 add_subwindow(title = new BC_Title(x, y, "X:"));
2351 this->x = new CWindowCoord(this, x1, y, (float)0.0);
2352 this->x->create_objects();
2353 add_subwindow(draw_markers = new CWindowMaskDrawMarkers(mwindow, this, del_x, y));
2354 y += this->x->get_h() + margin;
2355 add_subwindow(title = new BC_Title(x, y, "Y:"));
2356 this->y = new CWindowCoord(this, x1, y, (float)0.0);
2357 this->y->create_objects();
2358 add_subwindow(draw_boundary = new CWindowMaskDrawBoundary(mwindow, this, del_x, y));
2359 y += this->y->get_h() + 2*margin;
2360 add_subwindow(title_bar = new BC_TitleBar(x, y, get_w()-2*x, 20, 10, _("Pivot Point")));
2361 y += title_bar->get_h() + margin;
2363 add_subwindow(title = new BC_Title(x, y, "X:"));
2364 focus_x = new CWindowCoord(this, x1, y, (float)0.0);
2365 focus_x->create_objects();
2366 add_subwindow(focus = new CWindowMaskFocus(mwindow, this, del_x, y));
2367 y += focus_x->get_h() + margin;
2368 add_subwindow(title = new BC_Title(x, y, "Y:"));
2369 focus_y = new CWindowCoord(this, x1, y, (float)0.0);
2370 focus_y->create_objects();
2371 add_subwindow(draw_center = new CWindowMaskDrawCenter(mwindow, this, del_x, y));
2372 y += focus_x->get_h() + 2*margin;
2374 add_subwindow(bar = new BC_Bar(x, y, get_w()-2*x));
2375 y += bar->get_h() + margin;
2376 add_subwindow(this->apply_before_plugins = new CWindowMaskBeforePlugins(this, 10, y));
2377 y += this->apply_before_plugins->get_h();
2378 add_subwindow(this->disable_opengl_masking = new CWindowDisableOpenGLMasking(this, 10, y));
2379 y += this->disable_opengl_masking->get_h() + margin;
2380 add_subwindow(bar = new BC_Bar(x, y, get_w()-2*x));
2381 y += bar->get_h() + margin;
2384 add_subwindow(title = new BC_Title(x, y, _(
2385 "Shift+LMB: move an end point\n"
2386 "Ctrl+LMB: move a control point\n"
2387 "Alt+LMB: to drag translate the mask\n"
2388 "Shift+Key Delete to delete the mask\n"
2389 "Wheel Up/Dn: rotate around pointer\n"
2390 "Shift+Wheel Up/Dn: scale around pointer\n"
2391 "Shift+MMB: Toggle focus center at pointer")));
2396 void CWindowMaskGUI::get_keyframe(Track* &track,
2398 MaskAuto* &keyframe,
2406 track = mwindow->cwindow->calculate_affected_track();
2409 autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
2410 keyframe = (MaskAuto*)mwindow->cwindow->calculate_affected_auto(
2416 mask = keyframe->get_submask(mwindow->edl->session->cwindow_mask);
2423 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2424 mwindow->cwindow->gui->affected_point >= 0)
2426 point = mask->points.values[mwindow->cwindow->gui->affected_point];
2431 void CWindowMaskGUI::update()
2438 //printf("CWindowMaskGUI::update 1\n");
2439 get_keyframe(track, autos, keyframe, mask, point, 0);
2441 mask_track->update(!track ? "" : track->title);
2442 name->update_items(keyframe);
2443 const char *text = "";
2444 int sz = !keyframe ? 0 : keyframe->masks.size();
2445 int k = mwindow->edl->session->cwindow_mask;
2446 if( k >= 0 && k < sz )
2447 text = keyframe->masks[k]->name;
2449 update_buttons(keyframe, k);
2451 x->update(point->x);
2452 y->update(point->y);
2455 double position = mwindow->edl->local_session->get_selectionstart(1);
2456 int64_t position_i = track->to_units(position, 0);
2457 feather->update(autos->get_feather(position_i, k, PLAY_FORWARD));
2458 fade->update(autos->get_fader(position_i, k, PLAY_FORWARD));
2461 apply_before_plugins->update(keyframe->apply_before_plugins);
2462 disable_opengl_masking->update(keyframe->disable_opengl_masking);
2464 active_point->update((int64_t)mwindow->cwindow->gui->affected_point);
2467 void CWindowMaskGUI::handle_event()
2474 get_keyframe(track, autos, keyframe, mask, point, 0);
2476 mwindow->undo->update_undo_before(_("mask point"), this);
2480 #ifdef USE_KEYFRAME_SPANNING
2481 // Create temp keyframe
2482 MaskAuto temp_keyframe(mwindow->edl, autos);
2483 temp_keyframe.copy_data(keyframe);
2484 // Get affected point in temp keyframe
2485 mask = temp_keyframe.get_submask(mwindow->edl->session->cwindow_mask);
2486 if(mwindow->cwindow->gui->affected_point < mask->points.total &&
2487 mwindow->cwindow->gui->affected_point >= 0)
2489 point = mask->points.values[mwindow->cwindow->gui->affected_point];
2494 point->x = atof(x->get_text());
2495 point->y = atof(y->get_text());
2496 // Commit to spanned keyframes
2497 autos->update_parameter(&temp_keyframe);
2500 point->x = atof(x->get_text());
2501 point->y = atof(y->get_text());
2506 mwindow->undo->update_undo_after(_("mask point"), LOAD_AUTOMATION);
2509 void CWindowMaskGUI::update_preview()
2512 CWindowGUI *cgui = mwindow->cwindow->gui;
2513 cgui->lock_window("CWindowMaskGUI::update_preview");
2514 cgui->sync_parameters(CHANGE_PARAMS, 0, 1);
2515 cgui->unlock_window();
2516 lock_window("CWindowMaskGUI::update_preview");
2519 void CWindowMaskGUI::set_focused(int v, float cx, float cy)
2521 focus_x->update(cx);
2522 focus_y->update(cy);
2523 focus->update(focused = v);
2526 void CWindowMaskGUI::update_buttons(MaskAuto *keyframe, int k)
2528 int text_color = get_resources()->default_text_color;
2529 int high_color = get_resources()->button_highlighted;
2530 for( int i=0; i<SUBMASKS; ++i ) {
2531 int color = text_color;
2533 SubMask *submask = keyframe->get_submask(i);
2534 if( submask && submask->points.size() )
2537 mask_blabels[i]->set_color(color);
2538 mask_buttons[i]->update(i==k ? 1 : 0);
2542 CWindowRulerGUI::CWindowRulerGUI(MWindow *mwindow, CWindowTool *thread)
2543 : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Ruler"), 320, 240)
2547 CWindowRulerGUI::~CWindowRulerGUI()
2551 void CWindowRulerGUI::create_objects()
2553 int x = 10, y = 10, x1 = 100;
2556 lock_window("CWindowRulerGUI::create_objects");
2557 add_subwindow(title = new BC_Title(x, y, _("Current:")));
2558 add_subwindow(current = new BC_TextBox(x1, y, 200, 1, ""));
2559 y += title->get_h() + 5;
2560 add_subwindow(title = new BC_Title(x, y, _("Point 1:")));
2561 add_subwindow(point1 = new BC_TextBox(x1, y, 200, 1, ""));
2562 y += title->get_h() + 5;
2563 add_subwindow(title = new BC_Title(x, y, _("Point 2:")));
2564 add_subwindow(point2 = new BC_TextBox(x1, y, 200, 1, ""));
2565 y += title->get_h() + 5;
2566 add_subwindow(title = new BC_Title(x, y, _("Deltas:")));
2567 add_subwindow(deltas = new BC_TextBox(x1, y, 200, 1, ""));
2568 y += title->get_h() + 5;
2569 add_subwindow(title = new BC_Title(x, y, _("Distance:")));
2570 add_subwindow(distance = new BC_TextBox(x1, y, 200, 1, ""));
2571 y += title->get_h() + 5;
2572 add_subwindow(title = new BC_Title(x, y, _("Angle:")));
2573 add_subwindow(angle = new BC_TextBox(x1, y, 200, 1, ""));
2574 y += title->get_h() + 10;
2575 char string[BCTEXTLEN];
2577 _("Press Ctrl to lock ruler to the\nnearest 45%c%c angle."),
2578 0xc2, 0xb0); // degrees utf
2579 add_subwindow(title = new BC_Title(x,
2582 y += title->get_h() + 10;
2583 sprintf(string, _("Press Alt to translate the ruler."));
2584 add_subwindow(title = new BC_Title(x,
2591 void CWindowRulerGUI::update()
2593 char string[BCTEXTLEN];
2594 int cx = mwindow->session->cwindow_output_x;
2595 int cy = mwindow->session->cwindow_output_y;
2596 sprintf(string, "%d, %d", cx, cy);
2597 current->update(string);
2598 double x1 = mwindow->edl->session->ruler_x1;
2599 double y1 = mwindow->edl->session->ruler_y1;
2600 sprintf(string, "%.0f, %.0f", x1, y1);
2601 point1->update(string);
2602 double x2 = mwindow->edl->session->ruler_x2;
2603 double y2 = mwindow->edl->session->ruler_y2;
2604 sprintf(string, "%.0f, %.0f", x2, y2);
2605 point2->update(string);
2606 double dx = x2 - x1, dy = y2 - y1;
2607 sprintf(string, "%s%.0f, %s%.0f", (dx>=0? "+":""), dx, (dy>=0? "+":""), dy);
2608 deltas->update(string);
2609 double d = sqrt(dx*dx + dy*dy);
2610 sprintf(string, _("%0.01f pixels"), d);
2611 distance->update(string);
2612 double a = d > 0 ? (atan2(-dy, dx) * 180/M_PI) : 0.;
2613 sprintf(string, "%0.02f %c%c", a, 0xc2, 0xb0);
2614 angle->update(string);
2617 void CWindowRulerGUI::handle_event()