4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "apatchgui.h"
26 #include "bcwindowbase.h"
28 #include "cwindowgui.h"
31 #include "edlsession.h"
33 #include "floatauto.h"
35 #include "gwindowgui.h"
39 #include "keyframepopup.h"
41 #include "localsession.h"
42 #include "maincursor.h"
45 #include "mwindowgui.h"
50 #include "timelinepane.h"
52 #include "trackcanvas.h"
55 KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
56 : BC_PopupMenu(0, 0, 0, "", 0)
58 this->mwindow = mwindow;
68 key_mode_displayed = false;
69 key_edit_displayed = false;
72 KeyframePopup::~KeyframePopup()
74 if( !key_mode_displayed ) {
81 if( !key_edit_displayed ) {
86 void KeyframePopup::create_objects()
88 add_item(key_show = new KeyframePopupShow(mwindow, this));
89 add_item(key_hide = new KeyframePopupHide(mwindow, this));
90 add_item(key_delete = new KeyframePopupDelete(mwindow, this));
91 add_item(key_copy = new KeyframePopupCopy(mwindow, this));
93 key_edit = new KeyframePopupEdit(mwindow, this);
94 key_mbar = new BC_MenuItem("-");
95 key_smooth = new KeyframePopupCurveMode(mwindow, this, FloatAuto::SMOOTH);
96 key_linear = new KeyframePopupCurveMode(mwindow, this, FloatAuto::LINEAR);
97 key_free_t = new KeyframePopupCurveMode(mwindow, this, FloatAuto::TFREE );
98 key_free = new KeyframePopupCurveMode(mwindow, this, FloatAuto::FREE );
101 int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
103 key_show->set_text(_("Show Plugin Settings"));
104 this->keyframe_plugin = plugin;
105 this->keyframe_auto = keyframe;
106 this->keyframe_autos = 0;
107 this->keyframe_automation = 0;
108 handle_curve_mode(0, 0);
112 int KeyframePopup::update(Automation *automation, Autos *autos, Auto *auto_keyframe)
114 key_show->set_text(_(GWindowGUI::auto_text[autos->autoidx]));
115 this->keyframe_plugin = 0;
116 this->keyframe_automation = automation;
117 this->keyframe_autos = autos;
118 this->keyframe_auto = auto_keyframe;
119 handle_curve_mode(autos, auto_keyframe);
122 double current_position = mwindow->edl->local_session->get_selectionstart(1);
123 double new_position = keyframe_automation->track->from_units(keyframe_auto->position);
124 mwindow->edl->local_session->set_selectionstart(new_position);
125 mwindow->edl->local_session->set_selectionend(new_position);
126 if (current_position != new_position)
128 mwindow->edl->local_session->set_selectionstart(new_position);
129 mwindow->edl->local_session->set_selectionend(new_position);
130 mwindow->gui->lock_window();
131 mwindow->gui->update(1, 1, 1, 1, 1, 1, 0);
132 mwindow->gui->unlock_window();
137 void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
138 // determines the type of automation node. if floatauto, adds
139 // menu entries showing the curve mode of the node
142 if( !key_edit_displayed && keyframe_plugin ) {
144 key_edit_displayed = true;
146 else if( key_edit_displayed && !keyframe_plugin ) {
147 remove_item(key_edit);
148 key_edit_displayed = false;
151 if(!key_mode_displayed && autos && autos->get_type() == AUTOMATION_TYPE_FLOAT)
152 { // append additional menu entries showing the curve_mode
154 add_item(key_smooth);
155 add_item(key_linear);
156 add_item(key_free_t);
158 key_mode_displayed = true;
160 else if(key_mode_displayed && (!autos || autos->get_type() != AUTOMATION_TYPE_FLOAT))
161 { // remove additional menu entries
162 remove_item(key_free);
163 remove_item(key_free_t);
164 remove_item(key_linear);
165 remove_item(key_smooth);
166 remove_item(key_mbar);
167 key_mode_displayed = false;
169 if(key_mode_displayed && auto_keyframe)
170 { // set checkmarks to display current mode
171 key_smooth->toggle_mode((FloatAuto*)auto_keyframe);
172 key_linear->toggle_mode((FloatAuto*)auto_keyframe);
173 key_free_t->toggle_mode((FloatAuto*)auto_keyframe);
174 key_free ->toggle_mode((FloatAuto*)auto_keyframe);
179 KeyframePopupDelete::KeyframePopupDelete(MWindow *mwindow, KeyframePopup *popup)
180 : BC_MenuItem(_("Delete keyframe"))
182 this->mwindow = mwindow;
186 KeyframePopupDelete::~KeyframePopupDelete()
190 int KeyframePopupDelete::handle_event()
192 mwindow->undo->update_undo_before(_("delete keyframe"), 0);
193 mwindow->speed_before();
194 delete popup->keyframe_auto;
195 mwindow->speed_after(1);
196 mwindow->undo->update_undo_after(_("delete keyframe"), LOAD_ALL);
198 mwindow->save_backup();
199 mwindow->gui->update(0, 1, // 1 for incremental drawing. 2 for full refresh
201 mwindow->update_plugin_guis();
202 mwindow->restart_brender();
203 mwindow->sync_parameters(CHANGE_EDL);
208 KeyframePopupHide::KeyframePopupHide(MWindow *mwindow, KeyframePopup *popup)
209 : BC_MenuItem(_("Hide keyframe type"))
211 this->mwindow = mwindow;
215 KeyframePopupHide::~KeyframePopupHide()
219 int KeyframePopupHide::handle_event()
221 if( popup->keyframe_autos )
222 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
226 KeyframePopupShow::KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup)
227 : BC_MenuItem(_("Show keyframe settings"))
229 this->mwindow = mwindow;
233 KeyframePopupShow::~KeyframePopupShow()
237 int KeyframePopupShow::handle_event()
239 MWindowGUI *mgui = mwindow->gui;
240 CWindowGUI *cgui = mwindow->cwindow->gui;
241 int cx = mgui->get_relative_cursor_x()+15, cy = mgui->get_relative_cursor_y()-15;
242 delete mgui->keyvalue_popup;
243 mgui->keyvalue_popup = 0;
245 if( popup->keyframe_plugin ) {
246 mwindow->update_plugin_guis();
247 mwindow->show_plugin(popup->keyframe_plugin);
249 else if( popup->keyframe_automation ) {
253 switch( popup->keyframe_autos->autoidx ) {
254 case AUTOMATION_CAMERA_X:
255 case AUTOMATION_CAMERA_Y:
256 case AUTOMATION_CAMERA_Z: {
257 cgui->set_operation(CWINDOW_CAMERA);
260 case AUTOMATION_PROJECTOR_X:
261 case AUTOMATION_PROJECTOR_Y:
262 case AUTOMATION_PROJECTOR_Z: {
263 cgui->set_operation(CWINDOW_PROJECTOR);
266 case AUTOMATION_MASK: {
267 cgui->set_operation(CWINDOW_MASK);
272 PatchGUI *patchgui = mwindow->get_patchgui(popup->keyframe_automation->track);
273 if( !patchgui ) break;
275 switch( popup->keyframe_autos->autoidx ) {
276 case AUTOMATION_MODE: {
277 VKeyModePatch *mode = new VKeyModePatch(mwindow, (VPatchGUI *)patchgui);
278 mgui->add_subwindow(mode);
279 mode->create_objects();
280 mode->activate_menu();
281 mgui->keyvalue_popup = mode;
284 case AUTOMATION_PAN: {
285 AKeyPanPatch *pan = new AKeyPanPatch(mwindow, (APatchGUI *)patchgui);
286 mgui->add_subwindow(pan);
287 pan->create_objects();
288 pan->activate(cx, cy);
289 mgui->keyvalue_popup = pan;
292 case AUTOMATION_FADE: {
293 switch( patchgui->data_type ) {
295 AKeyFadePatch *fade = new AKeyFadePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
296 mgui->add_subwindow(fade);
297 fade->create_objects();
298 mgui->keyvalue_popup = fade;
301 VKeyFadePatch *fade = new VKeyFadePatch(mwindow, (VPatchGUI *)patchgui, cx, cy);
302 mgui->add_subwindow(fade);
303 fade->create_objects();
304 mgui->keyvalue_popup = fade;
309 case AUTOMATION_SPEED: {
310 KeySpeedPatch *speed = new KeySpeedPatch(mwindow, patchgui, cx, cy);
311 mgui->add_subwindow(speed);
312 speed->create_objects();
313 mgui->keyvalue_popup = speed;
316 case AUTOMATION_MUTE: {
317 KeyMutePatch *mute = new KeyMutePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
318 mgui->add_subwindow(mute);
319 mute->create_objects();
320 mgui->keyvalue_popup = mute;
326 // ensure bringing to front
328 mwindow->show_cwindow();
329 CPanelToolWindow *panel_tool_window =
330 (CPanelToolWindow *)cgui->composite_panel->operation[CWINDOW_TOOL_WINDOW];
331 panel_tool_window->set_shown(0);
332 panel_tool_window->set_shown(1);
334 cgui->unlock_window();
341 KeyframePopupCopy::KeyframePopupCopy(MWindow *mwindow, KeyframePopup *popup)
342 : BC_MenuItem(_("Copy keyframe"))
344 this->mwindow = mwindow;
348 KeyframePopupCopy::~KeyframePopupCopy()
352 int KeyframePopupCopy::handle_event()
356 we want to copy just keyframe under cursor, NOT all keyframes at this frame
357 - very hard to do, so this is good approximation for now...
361 if (popup->keyframe_automation)
364 EDL *edl = mwindow->edl;
365 Track *track = popup->keyframe_automation->track;
366 int64_t position = popup->keyframe_auto->position;
368 // first find out type of our auto
370 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos)
371 autoconf.projector = 1;
372 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
374 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos)
376 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
378 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
380 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
382 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
384 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
386 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
390 // now create a clipboard
391 file.tag.set_title("AUTO_CLIPBOARD");
392 file.tag.set_property("LENGTH", 0);
393 file.tag.set_property("FRAMERATE", edl->session->frame_rate);
394 file.tag.set_property("SAMPLERATE", edl->session->sample_rate);
396 file.append_newline();
397 file.append_newline();
399 /* track->copy_automation(position,
405 file.tag.set_title("TRACK");
407 track->save_header(&file);
409 file.append_newline();
411 track->automation->copy(position,
417 file.tag.set_title("/TRACK");
419 file.append_newline();
420 file.append_newline();
421 file.append_newline();
422 file.append_newline();
424 file.tag.set_title("/AUTO_CLIPBOARD");
426 file.append_newline();
427 file.terminate_string();
429 mwindow->gui->lock_window();
430 mwindow->gui->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
431 mwindow->gui->unlock_window();
435 mwindow->copy_automation();
441 KeyframePopupCurveMode::KeyframePopupCurveMode(
443 KeyframePopup *popup,
445 : BC_MenuItem( get_labeltext(curve_mode))
447 this->curve_mode = curve_mode;
448 this->mwindow = mwindow;
452 KeyframePopupCurveMode::~KeyframePopupCurveMode() { }
455 const char* KeyframePopupCurveMode::get_labeltext(int mode)
458 case FloatAuto::SMOOTH: return _("smooth curve");
459 case FloatAuto::LINEAR: return _("linear segments");
460 case FloatAuto::TFREE: return _("tangent edit");
461 case FloatAuto::FREE: return _("disjoint edit");
463 return _("misconfigured");
467 void KeyframePopupCurveMode::toggle_mode(FloatAuto *keyframe)
469 set_checked(curve_mode == keyframe->curve_mode);
473 int KeyframePopupCurveMode::handle_event()
475 if (popup->keyframe_autos &&
476 popup->keyframe_autos->get_type() == AUTOMATION_TYPE_FLOAT)
478 mwindow->undo->update_undo_before(_("change keyframe curve mode"), 0);
479 ((FloatAuto*)popup->keyframe_auto)->
480 change_curve_mode((FloatAuto::t_mode)curve_mode);
482 // if we switched to some "auto" mode, this may imply a
483 // real change to parameters, so this needs to be undoable...
484 mwindow->undo->update_undo_after(_("change keyframe curve mode"), LOAD_ALL);
485 mwindow->save_backup();
487 mwindow->gui->update(0, 1, 0,0,0,0,0); // incremental redraw for canvas
488 mwindow->cwindow->update(0,0, 1, 0,0); // redraw tool window in compositor
489 mwindow->update_plugin_guis();
490 mwindow->restart_brender();
491 mwindow->sync_parameters(CHANGE_EDL);
497 KeyframePopupEdit::KeyframePopupEdit(MWindow *mwindow, KeyframePopup *popup)
498 : BC_MenuItem(_("Edit Params..."))
500 this->mwindow = mwindow;
504 int KeyframePopupEdit::handle_event()
506 mwindow->show_keyframe_gui(popup->keyframe_plugin);
511 KeyframeHidePopup::KeyframeHidePopup(MWindow *mwindow, MWindowGUI *gui)
512 : BC_PopupMenu(0, 0, 0, "", 0)
514 this->mwindow = mwindow;
516 this->keyframe_autos = 0;
519 KeyframeHidePopup::~KeyframeHidePopup()
523 void KeyframeHidePopup::create_objects()
525 add_item(new KeyframeHideItem(mwindow, this));
528 int KeyframeHidePopup::update(Autos *autos)
530 this->keyframe_autos = autos;
534 KeyframeHideItem::KeyframeHideItem(MWindow *mwindow, KeyframeHidePopup *popup)
535 : BC_MenuItem(_("Hide keyframe type"))
537 this->mwindow = mwindow;
542 int KeyframeHideItem::handle_event()
544 if( popup->keyframe_autos )
545 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
551 KeyMutePatch::KeyMutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
552 : BC_SubWindow(x, y, 100, 20, GWindowGUI::auto_colors[AUTOMATION_MUTE])
554 this->mwindow = mwindow;
558 void KeyMutePatch::create_objects()
560 key_mute_checkbox = new KeyMuteValue(this);
561 add_subwindow(key_mute_checkbox);
562 key_mute_checkbox->activate();
566 KeyMuteValue::KeyMuteValue(KeyMutePatch *key_mute_patch)
567 : BC_CheckBox(0,0, key_mute_patch->mwindow->
568 get_int_auto(key_mute_patch->patch, AUTOMATION_MUTE)->value,
569 _("Mute"), MEDIUMFONT, RED)
571 this->key_mute_patch = key_mute_patch;
574 int KeyMuteValue::button_release_event()
576 BC_CheckBox::button_release_event();
577 MWindowGUI *mgui = key_mute_patch->mwindow->gui;
578 delete mgui->keyvalue_popup;
579 mgui->keyvalue_popup = 0;
583 int KeyMuteValue::handle_event()
585 MWindow *mwindow = key_mute_patch->mwindow;
586 PatchGUI *patch = key_mute_patch->patch;
588 patch->change_source = 1;
589 double position = mwindow->edl->local_session->get_selectionstart(1);
590 Autos *mute_autos = patch->track->automation->autos[AUTOMATION_MUTE];
591 int need_undo = !mute_autos->auto_exists_for_editing(position);
592 mwindow->undo->update_undo_before(_("mute"), need_undo ? 0 : this);
593 IntAuto *current = (IntAuto*)mute_autos->get_auto_for_editing(position);
594 current->value = this->get_value();
595 mwindow->undo->update_undo_after(_("mute"), LOAD_AUTOMATION);
596 patch->change_source = 0;
598 mwindow->sync_parameters(CHANGE_PARAMS);
599 if( mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE] ) {
600 mwindow->gui->update_patchbay();
601 mwindow->gui->draw_overlays(1);
606 KeySpeedPatch::KeySpeedPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
607 : BC_SubWindow(x,y, 200,20, GWindowGUI::auto_colors[AUTOMATION_SPEED])
609 this->mwindow = mwindow;
613 void KeySpeedPatch::create_objects()
616 float v = mwindow->get_float_auto(patch, AUTOMATION_SPEED)->get_value();
617 add_subwindow(key_speed_text = new KeySpeedText(this, x, y, 64, v));
618 x += key_speed_text->get_w();
619 VFrame **lok_images = mwindow->theme->get_image_set("lok");
620 int w1 = get_w() - x - lok_images[0]->get_w();
621 add_subwindow(key_speed_slider = new KeySpeedSlider(this, x, y, w1, v));
622 x += key_speed_slider->get_w();
623 add_subwindow(key_speed_ok = new KeySpeedOK(this, x, y, lok_images));
628 int KeySpeedPatch::cursor_enter_event()
631 mwindow->speed_before();
635 int KeySpeedPatch::cursor_leave_event()
637 if( is_event_win() ) {
638 mwindow->speed_after(1);
639 mwindow->resync_guis();
644 void KeySpeedPatch::update(float v)
646 key_speed_text->update(v);
647 key_speed_slider->update(v);
651 void KeySpeedPatch::update_speed(float v)
653 patch->change_source = 1;
654 double position = mwindow->edl->local_session->get_selectionstart(1);
655 Track *track = patch->track;
656 Autos *speed_autos = track->automation->autos[AUTOMATION_SPEED];
657 int need_undo = !speed_autos->auto_exists_for_editing(position);
659 mwindow->undo->update_undo_before(_("speed"), need_undo ? 0 : this);
660 FloatAuto *current = (FloatAuto*)speed_autos->get_auto_for_editing(position);
661 float change = v - current->get_value();
662 current->set_value(v);
663 if( track->gang && track->record ) {
664 TrackCanvas *track_canvas = patch->patchbay->pane->canvas;
665 track_canvas->fill_ganged_autos(1, change, track, current);
666 track_canvas->update_ganged_autos(0, track, current);
667 track_canvas->clear_ganged_autos();
669 mwindow->undo->update_undo_after(_("speed"), LOAD_AUTOMATION+LOAD_EDITS);
670 patch->change_source = 0;
672 mwindow->sync_parameters(CHANGE_PARAMS);
673 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_SPEED]) {
674 mwindow->gui->draw_overlays(1);
678 KeySpeedOK::KeySpeedOK(KeySpeedPatch *key_speed_patch, int x, int y, VFrame **images)
679 : BC_Button(x, y, images)
681 this->key_speed_patch = key_speed_patch;
684 int KeySpeedOK::handle_event()
686 MWindow *mwindow = key_speed_patch->mwindow;
687 mwindow->speed_after(1);
688 mwindow->resync_guis();
689 MWindowGUI *mgui = mwindow->gui;
690 delete mgui->keyvalue_popup;
691 mgui->keyvalue_popup = 0;
695 KeySpeedText::KeySpeedText(KeySpeedPatch *key_speed_patch, int x, int y, int w, float v)
696 : BC_TextBox(x, y, w, 1, v, 1, MEDIUMFONT, 2)
698 this->key_speed_patch = key_speed_patch;
701 int KeySpeedText::handle_event()
703 float v = atof(get_text());
704 key_speed_patch->update(v);
705 return get_keypress() != RETURN ? 1 :
706 key_speed_patch->key_speed_ok->handle_event();
709 KeySpeedSlider::KeySpeedSlider(KeySpeedPatch *key_speed_patch,
710 int x, int y, int w, float v)
711 : BC_FSlider(x, y, 0, w, w,
712 key_speed_patch->mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_SPEED],
713 key_speed_patch->mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_SPEED],
716 this->key_speed_patch = key_speed_patch;
717 key_speed_patch->mwindow->speed_before();
721 KeySpeedSlider::~KeySpeedSlider()
725 int KeySpeedSlider::handle_event()
729 set_tooltip(get_caption());
731 key_speed_patch->update(get_value());