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"
38 #include "keyframepopup.h"
40 #include "localsession.h"
41 #include "maincursor.h"
44 #include "mwindowgui.h"
48 #include "timelinepane.h"
52 KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
53 : BC_PopupMenu(0, 0, 0, "", 0)
55 this->mwindow = mwindow;
65 key_mode_displayed = false;
66 key_edit_displayed = false;
69 KeyframePopup::~KeyframePopup()
71 if( !key_mode_displayed ) {
78 if( !key_edit_displayed ) {
83 void KeyframePopup::create_objects()
85 add_item(key_show = new KeyframePopupShow(mwindow, this));
86 add_item(key_hide = new KeyframePopupHide(mwindow, this));
87 add_item(key_delete = new KeyframePopupDelete(mwindow, this));
88 add_item(key_copy = new KeyframePopupCopy(mwindow, this));
90 key_edit = new KeyframePopupEdit(mwindow, this);
91 key_mbar = new BC_MenuItem("-");
92 key_smooth = new KeyframePopupCurveMode(mwindow, this, FloatAuto::SMOOTH);
93 key_linear = new KeyframePopupCurveMode(mwindow, this, FloatAuto::LINEAR);
94 key_free_t = new KeyframePopupCurveMode(mwindow, this, FloatAuto::TFREE );
95 key_free = new KeyframePopupCurveMode(mwindow, this, FloatAuto::FREE );
98 int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
100 key_show->set_text(_("Show Plugin Settings"));
101 this->keyframe_plugin = plugin;
102 this->keyframe_auto = keyframe;
103 this->keyframe_autos = 0;
104 this->keyframe_automation = 0;
105 handle_curve_mode(0, 0);
109 int KeyframePopup::update(Automation *automation, Autos *autos, Auto *auto_keyframe)
111 key_show->set_text(_(GWindowGUI::auto_text[autos->autoidx]));
112 this->keyframe_plugin = 0;
113 this->keyframe_automation = automation;
114 this->keyframe_autos = autos;
115 this->keyframe_auto = auto_keyframe;
116 handle_curve_mode(autos, auto_keyframe);
119 double current_position = mwindow->edl->local_session->get_selectionstart(1);
120 double new_position = keyframe_automation->track->from_units(keyframe_auto->position);
121 mwindow->edl->local_session->set_selectionstart(new_position);
122 mwindow->edl->local_session->set_selectionend(new_position);
123 if (current_position != new_position)
125 mwindow->edl->local_session->set_selectionstart(new_position);
126 mwindow->edl->local_session->set_selectionend(new_position);
127 mwindow->gui->lock_window();
128 mwindow->gui->update(1, 1, 1, 1, 1, 1, 0);
129 mwindow->gui->unlock_window();
134 void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
135 // determines the type of automation node. if floatauto, adds
136 // menu entries showing the curve mode of the node
139 if( !key_edit_displayed && keyframe_plugin ) {
141 key_edit_displayed = true;
143 else if( key_edit_displayed && !keyframe_plugin ) {
144 remove_item(key_edit);
145 key_edit_displayed = false;
148 if(!key_mode_displayed && autos && autos->get_type() == AUTOMATION_TYPE_FLOAT)
149 { // append additional menu entries showing the curve_mode
151 add_item(key_smooth);
152 add_item(key_linear);
153 add_item(key_free_t);
155 key_mode_displayed = true;
157 else if(key_mode_displayed && (!autos || autos->get_type() != AUTOMATION_TYPE_FLOAT))
158 { // remove additional menu entries
159 remove_item(key_free);
160 remove_item(key_free_t);
161 remove_item(key_linear);
162 remove_item(key_smooth);
163 remove_item(key_mbar);
164 key_mode_displayed = false;
166 if(key_mode_displayed && auto_keyframe)
167 { // set checkmarks to display current mode
168 key_smooth->toggle_mode((FloatAuto*)auto_keyframe);
169 key_linear->toggle_mode((FloatAuto*)auto_keyframe);
170 key_free_t->toggle_mode((FloatAuto*)auto_keyframe);
171 key_free ->toggle_mode((FloatAuto*)auto_keyframe);
176 KeyframePopupDelete::KeyframePopupDelete(MWindow *mwindow, KeyframePopup *popup)
177 : BC_MenuItem(_("Delete keyframe"))
179 this->mwindow = mwindow;
183 KeyframePopupDelete::~KeyframePopupDelete()
187 int KeyframePopupDelete::handle_event()
189 mwindow->undo->update_undo_before(_("delete keyframe"), 0);
190 delete popup->keyframe_auto;
191 mwindow->undo->update_undo_after(_("delete keyframe"), LOAD_ALL);
193 mwindow->save_backup();
194 mwindow->gui->update(0, 1, // 1 for incremental drawing. 2 for full refresh
196 mwindow->update_plugin_guis();
197 mwindow->restart_brender();
198 mwindow->sync_parameters(CHANGE_EDL);
203 KeyframePopupHide::KeyframePopupHide(MWindow *mwindow, KeyframePopup *popup)
204 : BC_MenuItem(_("Hide keyframe type"))
206 this->mwindow = mwindow;
210 KeyframePopupHide::~KeyframePopupHide()
214 int KeyframePopupHide::handle_event()
216 if( popup->keyframe_autos )
217 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
221 KeyframePopupShow::KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup)
222 : BC_MenuItem(_("Show keyframe settings"))
224 this->mwindow = mwindow;
228 KeyframePopupShow::~KeyframePopupShow()
232 PatchGUI *KeyframePopupShow::get_patchgui(Track *track)
234 PatchGUI *patchgui = 0;
235 TimelinePane **panes = mwindow->gui->pane;
236 for( int i=0; i<TOTAL_PANES && !patchgui; ++i ) {
237 if( !panes[i] ) continue;
238 PatchBay *patchbay = panes[i]->patchbay;
239 if( !patchbay ) continue;
240 for( int j=0; j<patchbay->patches.total && !patchgui; ++j ) {
241 if( patchbay->patches.values[j]->track == track )
242 patchgui = patchbay->patches.values[j];
248 int KeyframePopupShow::handle_event()
250 MWindowGUI *mgui = mwindow->gui;
251 CWindowGUI *cgui = mwindow->cwindow->gui;
252 int cx = mgui->get_relative_cursor_x()+15, cy = mgui->get_relative_cursor_y()-15;
253 delete mgui->keyvalue_popup;
254 mgui->keyvalue_popup = 0;
256 if( popup->keyframe_plugin ) {
257 mwindow->update_plugin_guis();
258 mwindow->show_plugin(popup->keyframe_plugin);
260 else if( popup->keyframe_automation ) {
264 switch( popup->keyframe_autos->autoidx ) {
265 case AUTOMATION_CAMERA_X:
266 case AUTOMATION_CAMERA_Y:
267 case AUTOMATION_CAMERA_Z: {
268 cgui->set_operation(CWINDOW_CAMERA);
271 case AUTOMATION_PROJECTOR_X:
272 case AUTOMATION_PROJECTOR_Y:
273 case AUTOMATION_PROJECTOR_Z: {
274 cgui->set_operation(CWINDOW_PROJECTOR);
277 case AUTOMATION_MASK: {
278 cgui->set_operation(CWINDOW_MASK);
283 PatchGUI *patchgui = get_patchgui(popup->keyframe_automation->track);
284 if( !patchgui ) break;
286 switch( popup->keyframe_autos->autoidx ) {
287 case AUTOMATION_MODE: {
288 VKeyModePatch *mode = new VKeyModePatch(mwindow, (VPatchGUI *)patchgui);
289 mgui->add_subwindow(mode);
290 mode->create_objects();
291 mode->activate_menu();
292 mgui->keyvalue_popup = mode;
295 case AUTOMATION_PAN: {
296 AKeyPanPatch *pan = new AKeyPanPatch(mwindow, (APatchGUI *)patchgui);
297 mgui->add_subwindow(pan);
298 pan->create_objects();
299 pan->activate(cx, cy);
300 mgui->keyvalue_popup = pan;
303 case AUTOMATION_FADE: {
304 switch( patchgui->data_type ) {
306 AKeyFadePatch *fade = new AKeyFadePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
307 mgui->add_subwindow(fade);
308 fade->create_objects();
309 mgui->keyvalue_popup = fade;
312 VKeyFadePatch *fade = new VKeyFadePatch(mwindow, (VPatchGUI *)patchgui, cx, cy);
313 mgui->add_subwindow(fade);
314 fade->create_objects();
315 mgui->keyvalue_popup = fade;
320 case AUTOMATION_SPEED: {
321 KeySpeedPatch *speed = new KeySpeedPatch(mwindow, patchgui, cx, cy);
322 mgui->add_subwindow(speed);
323 speed->create_objects();
324 mgui->keyvalue_popup = speed;
327 case AUTOMATION_MUTE: {
328 KeyMutePatch *mute = new KeyMutePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
329 mgui->add_subwindow(mute);
330 mute->create_objects();
331 mgui->keyvalue_popup = mute;
337 // ensure bringing to front
339 mwindow->show_cwindow();
340 CPanelToolWindow *panel_tool_window =
341 (CPanelToolWindow *)cgui->composite_panel->operation[CWINDOW_TOOL_WINDOW];
342 panel_tool_window->set_shown(0);
343 panel_tool_window->set_shown(1);
345 cgui->unlock_window();
352 KeyframePopupCopy::KeyframePopupCopy(MWindow *mwindow, KeyframePopup *popup)
353 : BC_MenuItem(_("Copy keyframe"))
355 this->mwindow = mwindow;
359 KeyframePopupCopy::~KeyframePopupCopy()
363 int KeyframePopupCopy::handle_event()
367 we want to copy just keyframe under cursor, NOT all keyframes at this frame
368 - very hard to do, so this is good approximation for now...
372 if (popup->keyframe_automation)
375 EDL *edl = mwindow->edl;
376 Track *track = popup->keyframe_automation->track;
377 int64_t position = popup->keyframe_auto->position;
379 // first find out type of our auto
381 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos)
382 autoconf.projector = 1;
383 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
385 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos)
387 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
389 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
391 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
393 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
395 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
397 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
401 // now create a clipboard
402 file.tag.set_title("AUTO_CLIPBOARD");
403 file.tag.set_property("LENGTH", 0);
404 file.tag.set_property("FRAMERATE", edl->session->frame_rate);
405 file.tag.set_property("SAMPLERATE", edl->session->sample_rate);
407 file.append_newline();
408 file.append_newline();
410 /* track->copy_automation(position,
416 file.tag.set_title("TRACK");
418 track->save_header(&file);
420 file.append_newline();
422 track->automation->copy(position,
428 file.tag.set_title("/TRACK");
430 file.append_newline();
431 file.append_newline();
432 file.append_newline();
433 file.append_newline();
435 file.tag.set_title("/AUTO_CLIPBOARD");
437 file.append_newline();
438 file.terminate_string();
440 mwindow->gui->lock_window();
441 mwindow->gui->get_clipboard()->to_clipboard(file.string,
443 SECONDARY_SELECTION);
444 mwindow->gui->unlock_window();
448 mwindow->copy_automation();
454 KeyframePopupCurveMode::KeyframePopupCurveMode(
456 KeyframePopup *popup,
458 : BC_MenuItem( get_labeltext(curve_mode))
460 this->curve_mode = curve_mode;
461 this->mwindow = mwindow;
465 KeyframePopupCurveMode::~KeyframePopupCurveMode() { }
468 const char* KeyframePopupCurveMode::get_labeltext(int mode)
471 case FloatAuto::SMOOTH: return _("smooth curve");
472 case FloatAuto::LINEAR: return _("linear segments");
473 case FloatAuto::TFREE: return _("tangent edit");
474 case FloatAuto::FREE: return _("disjoint edit");
476 return _("misconfigured");
480 void KeyframePopupCurveMode::toggle_mode(FloatAuto *keyframe)
482 set_checked(curve_mode == keyframe->curve_mode);
486 int KeyframePopupCurveMode::handle_event()
488 if (popup->keyframe_autos &&
489 popup->keyframe_autos->get_type() == AUTOMATION_TYPE_FLOAT)
491 mwindow->undo->update_undo_before(_("change keyframe curve mode"), 0);
492 ((FloatAuto*)popup->keyframe_auto)->
493 change_curve_mode((FloatAuto::t_mode)curve_mode);
495 // if we switched to some "auto" mode, this may imply a
496 // real change to parameters, so this needs to be undoable...
497 mwindow->undo->update_undo_after(_("change keyframe curve mode"), LOAD_ALL);
498 mwindow->save_backup();
500 mwindow->gui->update(0, 1, 0,0,0,0,0); // incremental redraw for canvas
501 mwindow->cwindow->update(0,0, 1, 0,0); // redraw tool window in compositor
502 mwindow->update_plugin_guis();
503 mwindow->restart_brender();
504 mwindow->sync_parameters(CHANGE_EDL);
510 KeyframePopupEdit::KeyframePopupEdit(MWindow *mwindow, KeyframePopup *popup)
511 : BC_MenuItem(_("Edit Params..."))
513 this->mwindow = mwindow;
517 int KeyframePopupEdit::handle_event()
519 mwindow->show_keyframe_gui(popup->keyframe_plugin);
524 KeyframeHidePopup::KeyframeHidePopup(MWindow *mwindow, MWindowGUI *gui)
525 : BC_PopupMenu(0, 0, 0, "", 0)
527 this->mwindow = mwindow;
529 this->keyframe_autos = 0;
532 KeyframeHidePopup::~KeyframeHidePopup()
536 void KeyframeHidePopup::create_objects()
538 add_item(new KeyframeHideItem(mwindow, this));
541 int KeyframeHidePopup::update(Autos *autos)
543 this->keyframe_autos = autos;
547 KeyframeHideItem::KeyframeHideItem(MWindow *mwindow, KeyframeHidePopup *popup)
548 : BC_MenuItem(_("Hide keyframe type"))
550 this->mwindow = mwindow;
555 int KeyframeHideItem::handle_event()
557 if( popup->keyframe_autos )
558 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
564 KeyMutePatch::KeyMutePatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
565 : BC_SubWindow(x, y, 100, 20, GWindowGUI::auto_colors[AUTOMATION_MUTE])
567 this->mwindow = mwindow;
571 void KeyMutePatch::create_objects()
573 key_mute_checkbox = new KeyMuteValue(this);
574 add_subwindow(key_mute_checkbox);
575 key_mute_checkbox->activate();
579 KeyMuteValue::KeyMuteValue(KeyMutePatch *key_mute_patch)
580 : BC_CheckBox(0,0, key_mute_patch->mwindow->
581 get_int_auto(key_mute_patch->patch, AUTOMATION_MUTE)->value,
582 _("Mute"), MEDIUMFONT, RED)
584 this->key_mute_patch = key_mute_patch;
587 int KeyMuteValue::button_release_event()
589 BC_CheckBox::button_release_event();
593 void KeyMuteValue::update_edl()
595 MWindow *mwindow = key_mute_patch->mwindow;
596 PatchGUI *patch = key_mute_patch->patch;
597 double position = mwindow->edl->local_session->get_selectionstart(1);
598 Autos *mute_autos = patch->track->automation->autos[AUTOMATION_MUTE];
599 int need_undo = !mute_autos->auto_exists_for_editing(position);
600 mwindow->undo->update_undo_before(_("mute"), need_undo ? 0 : this);
601 IntAuto *current = (IntAuto*)mute_autos->get_auto_for_editing(position);
602 current->value = this->get_value();
603 mwindow->undo->update_undo_after(_("mute"), LOAD_AUTOMATION);
606 int KeyMuteValue::handle_event()
608 MWindow *mwindow = key_mute_patch->mwindow;
609 PatchGUI *patch = key_mute_patch->patch;
610 patch->change_source = 1;
612 patch->change_source = 0;
613 mwindow->sync_parameters(CHANGE_PARAMS);
614 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MUTE]) {
615 mwindow->gui->update_patchbay();
616 mwindow->gui->draw_overlays(1);
621 KeySpeedPatch::KeySpeedPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
622 : BC_SubWindow(x,y, 200,20, GWindowGUI::auto_colors[AUTOMATION_SPEED])
624 this->mwindow = mwindow;
628 void KeySpeedPatch::create_objects()
630 key_speed_slider = new KeySpeedValue(this);
631 add_subwindow(key_speed_slider);
632 key_speed_slider->activate();
636 KeySpeedValue::KeySpeedValue(KeySpeedPatch *key_speed_patch)
637 : BC_FSlider(0,0, 0, key_speed_patch->get_w(), key_speed_patch->get_w(),
638 key_speed_patch->mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_SPEED],
639 key_speed_patch->mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_SPEED],
640 key_speed_patch->mwindow->get_float_auto(key_speed_patch->patch, AUTOMATION_SPEED)->get_value())
642 this->key_speed_patch = key_speed_patch;
646 KeySpeedValue::~KeySpeedValue()
650 int KeySpeedValue::button_release_event()
652 BC_FSlider::button_release_event();
656 void KeySpeedValue::update_edl()
658 MWindow *mwindow = key_speed_patch->mwindow;
659 PatchGUI *patch = key_speed_patch->patch;
660 double position = mwindow->edl->local_session->get_selectionstart(1);
661 Autos *speed_autos = patch->track->automation->autos[AUTOMATION_SPEED];
662 int need_undo = !speed_autos->auto_exists_for_editing(position);
663 mwindow->undo->update_undo_before(_("speed"), need_undo ? 0 : this);
664 FloatAuto *current = (FloatAuto*)speed_autos->get_auto_for_editing(position);
665 current->set_value(get_value());
666 mwindow->undo->update_undo_after(_("speed"), LOAD_AUTOMATION);
669 int KeySpeedValue::handle_event()
671 MWindow *mwindow = key_speed_patch->mwindow;
672 PatchGUI *patch = key_speed_patch->patch;
675 set_tooltip(get_caption());
678 patch->change_source = 1;
680 patch->change_source = 0;
681 mwindow->sync_parameters(CHANGE_PARAMS);
682 if(mwindow->edl->session->auto_conf->autos[AUTOMATION_SPEED]) {
683 mwindow->gui->draw_overlays(1);