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"
54 KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
55 : BC_PopupMenu(0, 0, 0, "", 0)
57 this->mwindow = mwindow;
67 key_mode_displayed = false;
68 key_edit_displayed = false;
71 KeyframePopup::~KeyframePopup()
73 if( !key_mode_displayed ) {
80 if( !key_edit_displayed ) {
85 void KeyframePopup::create_objects()
87 add_item(key_show = new KeyframePopupShow(mwindow, this));
88 add_item(key_hide = new KeyframePopupHide(mwindow, this));
89 add_item(key_delete = new KeyframePopupDelete(mwindow, this));
90 add_item(key_copy = new KeyframePopupCopy(mwindow, this));
92 key_edit = new KeyframePopupEdit(mwindow, this);
93 key_mbar = new BC_MenuItem("-");
94 key_smooth = new KeyframePopupCurveMode(mwindow, this, FloatAuto::SMOOTH);
95 key_linear = new KeyframePopupCurveMode(mwindow, this, FloatAuto::LINEAR);
96 key_free_t = new KeyframePopupCurveMode(mwindow, this, FloatAuto::TFREE );
97 key_free = new KeyframePopupCurveMode(mwindow, this, FloatAuto::FREE );
100 int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
102 key_show->set_text(_("Show Plugin Settings"));
103 this->keyframe_plugin = plugin;
104 this->keyframe_auto = keyframe;
105 this->keyframe_autos = 0;
106 this->keyframe_automation = 0;
107 handle_curve_mode(0, 0);
111 int KeyframePopup::update(Automation *automation, Autos *autos, Auto *auto_keyframe)
113 key_show->set_text(_(GWindowGUI::auto_text[autos->autoidx]));
114 this->keyframe_plugin = 0;
115 this->keyframe_automation = automation;
116 this->keyframe_autos = autos;
117 this->keyframe_auto = auto_keyframe;
118 handle_curve_mode(autos, auto_keyframe);
121 double current_position = mwindow->edl->local_session->get_selectionstart(1);
122 double new_position = keyframe_automation->track->from_units(keyframe_auto->position);
123 mwindow->edl->local_session->set_selectionstart(new_position);
124 mwindow->edl->local_session->set_selectionend(new_position);
125 if (current_position != new_position)
127 mwindow->edl->local_session->set_selectionstart(new_position);
128 mwindow->edl->local_session->set_selectionend(new_position);
129 mwindow->gui->lock_window();
130 mwindow->gui->update(1, 1, 1, 1, 1, 1, 0);
131 mwindow->gui->unlock_window();
136 void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
137 // determines the type of automation node. if floatauto, adds
138 // menu entries showing the curve mode of the node
141 if( !key_edit_displayed && keyframe_plugin ) {
143 key_edit_displayed = true;
145 else if( key_edit_displayed && !keyframe_plugin ) {
146 remove_item(key_edit);
147 key_edit_displayed = false;
150 if(!key_mode_displayed && autos && autos->get_type() == AUTOMATION_TYPE_FLOAT)
151 { // append additional menu entries showing the curve_mode
153 add_item(key_smooth);
154 add_item(key_linear);
155 add_item(key_free_t);
157 key_mode_displayed = true;
159 else if(key_mode_displayed && (!autos || autos->get_type() != AUTOMATION_TYPE_FLOAT))
160 { // remove additional menu entries
161 remove_item(key_free);
162 remove_item(key_free_t);
163 remove_item(key_linear);
164 remove_item(key_smooth);
165 remove_item(key_mbar);
166 key_mode_displayed = false;
168 if(key_mode_displayed && auto_keyframe)
169 { // set checkmarks to display current mode
170 key_smooth->toggle_mode((FloatAuto*)auto_keyframe);
171 key_linear->toggle_mode((FloatAuto*)auto_keyframe);
172 key_free_t->toggle_mode((FloatAuto*)auto_keyframe);
173 key_free ->toggle_mode((FloatAuto*)auto_keyframe);
178 KeyframePopupDelete::KeyframePopupDelete(MWindow *mwindow, KeyframePopup *popup)
179 : BC_MenuItem(_("Delete keyframe"))
181 this->mwindow = mwindow;
185 KeyframePopupDelete::~KeyframePopupDelete()
189 int KeyframePopupDelete::handle_event()
191 mwindow->undo->update_undo_before(_("delete keyframe"), 0);
192 mwindow->speed_before();
193 delete popup->keyframe_auto;
194 mwindow->speed_after(1);
195 mwindow->undo->update_undo_after(_("delete keyframe"), LOAD_ALL);
197 mwindow->save_backup();
198 mwindow->gui->update(0, 1, // 1 for incremental drawing. 2 for full refresh
200 mwindow->update_plugin_guis();
201 mwindow->restart_brender();
202 mwindow->sync_parameters(CHANGE_EDL);
207 KeyframePopupHide::KeyframePopupHide(MWindow *mwindow, KeyframePopup *popup)
208 : BC_MenuItem(_("Hide keyframe type"))
210 this->mwindow = mwindow;
214 KeyframePopupHide::~KeyframePopupHide()
218 int KeyframePopupHide::handle_event()
220 if( popup->keyframe_autos )
221 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
225 KeyframePopupShow::KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup)
226 : BC_MenuItem(_("Show keyframe settings"))
228 this->mwindow = mwindow;
232 KeyframePopupShow::~KeyframePopupShow()
236 int KeyframePopupShow::handle_event()
238 MWindowGUI *mgui = mwindow->gui;
239 CWindowGUI *cgui = mwindow->cwindow->gui;
240 int cx = mgui->get_relative_cursor_x()+15, cy = mgui->get_relative_cursor_y()-15;
241 delete mgui->keyvalue_popup;
242 mgui->keyvalue_popup = 0;
244 if( popup->keyframe_plugin ) {
245 mwindow->update_plugin_guis();
246 mwindow->show_plugin(popup->keyframe_plugin);
248 else if( popup->keyframe_automation ) {
252 switch( popup->keyframe_autos->autoidx ) {
253 case AUTOMATION_CAMERA_X:
254 case AUTOMATION_CAMERA_Y:
255 case AUTOMATION_CAMERA_Z: {
256 cgui->set_operation(CWINDOW_CAMERA);
259 case AUTOMATION_PROJECTOR_X:
260 case AUTOMATION_PROJECTOR_Y:
261 case AUTOMATION_PROJECTOR_Z: {
262 cgui->set_operation(CWINDOW_PROJECTOR);
265 case AUTOMATION_MASK: {
266 cgui->set_operation(CWINDOW_MASK);
271 PatchGUI *patchgui = mwindow->get_patchgui(popup->keyframe_automation->track);
272 if( !patchgui ) break;
274 switch( popup->keyframe_autos->autoidx ) {
275 case AUTOMATION_MODE: {
276 VKeyModePatch *mode = new VKeyModePatch(mwindow, (VPatchGUI *)patchgui);
277 mgui->add_subwindow(mode);
278 mode->create_objects();
279 mode->activate_menu();
280 mgui->keyvalue_popup = mode;
283 case AUTOMATION_PAN: {
284 AKeyPanPatch *pan = new AKeyPanPatch(mwindow, (APatchGUI *)patchgui);
285 mgui->add_subwindow(pan);
286 pan->create_objects();
287 pan->activate(cx, cy);
288 mgui->keyvalue_popup = pan;
291 case AUTOMATION_FADE: {
292 switch( patchgui->data_type ) {
294 AKeyFadePatch *fade = new AKeyFadePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
295 mgui->add_subwindow(fade);
296 fade->create_objects();
297 mgui->keyvalue_popup = fade;
300 VKeyFadePatch *fade = new VKeyFadePatch(mwindow, (VPatchGUI *)patchgui, cx, cy);
301 mgui->add_subwindow(fade);
302 fade->create_objects();
303 mgui->keyvalue_popup = fade;
308 case AUTOMATION_SPEED: {
309 KeySpeedPatch *speed = new KeySpeedPatch(mwindow, patchgui, cx, cy);
310 mgui->add_subwindow(speed);
311 speed->create_objects();
312 mgui->keyvalue_popup = speed;
315 case AUTOMATION_MUTE: {
316 KeyMutePatch *mute = new KeyMutePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
317 mgui->add_subwindow(mute);
318 mute->create_objects();
319 mgui->keyvalue_popup = mute;
325 // ensure bringing to front
327 mwindow->show_cwindow();
328 CPanelToolWindow *panel_tool_window =
329 (CPanelToolWindow *)cgui->composite_panel->operation[CWINDOW_TOOL_WINDOW];
330 panel_tool_window->set_shown(0);
331 panel_tool_window->set_shown(1);
333 cgui->unlock_window();
340 KeyframePopupCopy::KeyframePopupCopy(MWindow *mwindow, KeyframePopup *popup)
341 : BC_MenuItem(_("Copy keyframe"))
343 this->mwindow = mwindow;
347 KeyframePopupCopy::~KeyframePopupCopy()
351 int KeyframePopupCopy::handle_event()
355 we want to copy just keyframe under cursor, NOT all keyframes at this frame
356 - very hard to do, so this is good approximation for now...
360 if (popup->keyframe_automation)
363 EDL *edl = mwindow->edl;
364 Track *track = popup->keyframe_automation->track;
365 int64_t position = popup->keyframe_auto->position;
367 // first find out type of our auto
369 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos)
370 autoconf.projector = 1;
371 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
373 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos)
375 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
377 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
379 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
381 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
383 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
385 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
389 // now create a clipboard
390 file.tag.set_title("AUTO_CLIPBOARD");
391 file.tag.set_property("LENGTH", 0);
392 file.tag.set_property("FRAMERATE", edl->session->frame_rate);
393 file.tag.set_property("SAMPLERATE", edl->session->sample_rate);
395 file.append_newline();
396 file.append_newline();
398 /* track->copy_automation(position,
404 file.tag.set_title("TRACK");
406 track->save_header(&file);
408 file.append_newline();
410 track->automation->copy(position,
416 file.tag.set_title("/TRACK");
418 file.append_newline();
419 file.append_newline();
420 file.append_newline();
421 file.append_newline();
423 file.tag.set_title("/AUTO_CLIPBOARD");
425 file.append_newline();
426 file.terminate_string();
428 mwindow->gui->lock_window();
429 mwindow->gui->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
430 mwindow->gui->unlock_window();
434 mwindow->copy_automation();
440 KeyframePopupCurveMode::KeyframePopupCurveMode(
442 KeyframePopup *popup,
444 : BC_MenuItem( get_labeltext(curve_mode))
446 this->curve_mode = curve_mode;
447 this->mwindow = mwindow;
451 KeyframePopupCurveMode::~KeyframePopupCurveMode() { }
454 const char* KeyframePopupCurveMode::get_labeltext(int mode)
457 case FloatAuto::SMOOTH: return _("smooth curve");
458 case FloatAuto::LINEAR: return _("linear segments");
459 case FloatAuto::TFREE: return _("tangent edit");
460 case FloatAuto::FREE: return _("disjoint edit");
462 return _("misconfigured");
466 void KeyframePopupCurveMode::toggle_mode(FloatAuto *keyframe)
468 set_checked(curve_mode == keyframe->curve_mode);
472 int KeyframePopupCurveMode::handle_event()
474 if (popup->keyframe_autos &&
475 popup->keyframe_autos->get_type() == AUTOMATION_TYPE_FLOAT)
477 mwindow->undo->update_undo_before(_("change keyframe curve mode"), 0);
478 ((FloatAuto*)popup->keyframe_auto)->
479 change_curve_mode((FloatAuto::t_mode)curve_mode);
481 // if we switched to some "auto" mode, this may imply a
482 // real change to parameters, so this needs to be undoable...
483 mwindow->undo->update_undo_after(_("change keyframe curve mode"), LOAD_ALL);
484 mwindow->save_backup();
486 mwindow->gui->update(0, 1, 0,0,0,0,0); // incremental redraw for canvas
487 mwindow->cwindow->update(0,0, 1, 0,0); // redraw tool window in compositor
488 mwindow->update_plugin_guis();
489 mwindow->restart_brender();
490 mwindow->sync_parameters(CHANGE_EDL);
496 KeyframePopupEdit::KeyframePopupEdit(MWindow *mwindow, KeyframePopup *popup)
497 : BC_MenuItem(_("Edit Params..."))
499 this->mwindow = mwindow;
503 int KeyframePopupEdit::handle_event()
505 mwindow->show_keyframe_gui(popup->keyframe_plugin);
510 KeyframeHidePopup::KeyframeHidePopup(MWindow *mwindow, MWindowGUI *gui)
511 : BC_PopupMenu(0, 0, 0, "", 0)
513 this->mwindow = mwindow;
515 this->keyframe_autos = 0;
518 KeyframeHidePopup::~KeyframeHidePopup()
522 void KeyframeHidePopup::create_objects()
524 add_item(new KeyframeHideItem(mwindow, this));
527 int KeyframeHidePopup::update(Autos *autos)
529 this->keyframe_autos = autos;
533 KeyframeHideItem::KeyframeHideItem(MWindow *mwindow, KeyframeHidePopup *popup)
534 : BC_MenuItem(_("Hide keyframe type"))
536 this->mwindow = mwindow;
541 int KeyframeHideItem::handle_event()
543 if( popup->keyframe_autos )
544 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
550 KeyMutePatch::KeyMutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
551 : BC_SubWindow(x, y, 100, 20, GWindowGUI::auto_colors[AUTOMATION_MUTE])
553 this->mwindow = mwindow;
557 void KeyMutePatch::create_objects()
559 key_mute_checkbox = new KeyMuteValue(this);
560 add_subwindow(key_mute_checkbox);
561 key_mute_checkbox->activate();
565 KeyMuteValue::KeyMuteValue(KeyMutePatch *key_mute_patch)
566 : BC_CheckBox(0,0, key_mute_patch->mwindow->
567 get_int_auto(key_mute_patch->patch, AUTOMATION_MUTE)->value,
568 _("Mute"), MEDIUMFONT, RED)
570 this->key_mute_patch = key_mute_patch;
573 int KeyMuteValue::button_release_event()
575 BC_CheckBox::button_release_event();
576 MWindowGUI *mgui = key_mute_patch->mwindow->gui;
577 delete mgui->keyvalue_popup;
578 mgui->keyvalue_popup = 0;
582 int KeyMuteValue::handle_event()
584 MWindow *mwindow = key_mute_patch->mwindow;
585 PatchGUI *patch = key_mute_patch->patch;
587 patch->change_source = 1;
588 double position = mwindow->edl->local_session->get_selectionstart(1);
589 Autos *mute_autos = patch->track->automation->autos[AUTOMATION_MUTE];
590 int need_undo = !mute_autos->auto_exists_for_editing(position);
591 mwindow->undo->update_undo_before(_("mute"), need_undo ? 0 : this);
592 IntAuto *current = (IntAuto*)mute_autos->get_auto_for_editing(position);
593 current->value = this->get_value();
594 mwindow->undo->update_undo_after(_("mute"), LOAD_AUTOMATION);
595 patch->change_source = 0;
597 mwindow->sync_parameters(CHANGE_PARAMS);
598 if( mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE] ) {
599 mwindow->gui->update_patchbay();
600 mwindow->gui->draw_overlays(1);
605 KeySpeedPatch::KeySpeedPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
606 : BC_SubWindow(x,y, 200,20, GWindowGUI::auto_colors[AUTOMATION_SPEED])
608 this->mwindow = mwindow;
612 void KeySpeedPatch::create_objects()
615 float v = mwindow->get_float_auto(patch, AUTOMATION_SPEED)->get_value();
616 add_subwindow(key_speed_text = new KeySpeedText(this, x, y, 64, v));
617 x += key_speed_text->get_w();
618 VFrame **lok_images = mwindow->theme->get_image_set("lok");
619 int w1 = get_w() - x - lok_images[0]->get_w();
620 add_subwindow(key_speed_slider = new KeySpeedSlider(this, x, y, w1, v));
621 x += key_speed_slider->get_w();
622 add_subwindow(key_speed_ok = new KeySpeedOK(this, x, y, lok_images));
627 int KeySpeedPatch::cursor_enter_event()
630 mwindow->speed_before();
634 int KeySpeedPatch::cursor_leave_event()
636 if( is_event_win() ) {
637 mwindow->speed_after(1);
638 mwindow->resync_guis();
643 void KeySpeedPatch::update(float v)
645 key_speed_text->update(v);
646 key_speed_slider->update(v);
650 void KeySpeedPatch::update_speed(float v)
652 patch->change_source = 1;
653 double position = mwindow->edl->local_session->get_selectionstart(1);
654 Autos *speed_autos = patch->track->automation->autos[AUTOMATION_SPEED];
655 int need_undo = !speed_autos->auto_exists_for_editing(position);
657 mwindow->undo->update_undo_before(_("speed"), need_undo ? 0 : this);
658 FloatAuto *current = (FloatAuto*)speed_autos->get_auto_for_editing(position);
659 current->set_value(v);
660 mwindow->undo->update_undo_after(_("speed"), LOAD_AUTOMATION+LOAD_EDITS);
661 patch->change_source = 0;
663 mwindow->sync_parameters(CHANGE_PARAMS);
664 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_SPEED]) {
665 mwindow->gui->draw_overlays(1);
669 KeySpeedOK::KeySpeedOK(KeySpeedPatch *key_speed_patch, int x, int y, VFrame **images)
670 : BC_Button(x, y, images)
672 this->key_speed_patch = key_speed_patch;
675 int KeySpeedOK::handle_event()
677 MWindow *mwindow = key_speed_patch->mwindow;
678 mwindow->speed_after(1);
679 mwindow->resync_guis();
680 MWindowGUI *mgui = mwindow->gui;
681 delete mgui->keyvalue_popup;
682 mgui->keyvalue_popup = 0;
686 KeySpeedText::KeySpeedText(KeySpeedPatch *key_speed_patch, int x, int y, int w, float v)
687 : BC_TextBox(x, y, w, 1, v, 1, MEDIUMFONT, 2)
689 this->key_speed_patch = key_speed_patch;
692 int KeySpeedText::handle_event()
694 float v = atof(get_text());
695 key_speed_patch->update(v);
696 return get_keypress() != RETURN ? 1 :
697 key_speed_patch->key_speed_ok->handle_event();
700 KeySpeedSlider::KeySpeedSlider(KeySpeedPatch *key_speed_patch,
701 int x, int y, int w, float v)
702 : BC_FSlider(x, y, 0, w, w,
703 key_speed_patch->mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_SPEED],
704 key_speed_patch->mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_SPEED],
707 this->key_speed_patch = key_speed_patch;
708 key_speed_patch->mwindow->speed_before();
712 KeySpeedSlider::~KeySpeedSlider()
716 int KeySpeedSlider::handle_event()
720 set_tooltip(get_caption());
722 key_speed_patch->update(get_value());