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"
25 #include "bcwindowbase.h"
27 #include "cwindowgui.h"
30 #include "edlsession.h"
33 #include "gwindowgui.h"
35 #include "keyframepopup.h"
37 #include "localsession.h"
38 #include "maincursor.h"
41 #include "mwindowgui.h"
46 #include "vpatchgui.h"
48 KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
49 : BC_PopupMenu(0, 0, 0, "", 0)
51 this->mwindow = mwindow;
60 key_mode_displayed = false;
61 key_edit_displayed = false;
64 KeyframePopup::~KeyframePopup()
66 if( !key_mode_displayed ) {
73 if( !key_edit_displayed ) {
78 void KeyframePopup::create_objects()
80 add_item(key_show = new KeyframePopupShow(mwindow, this));
81 add_item(key_delete = new KeyframePopupDelete(mwindow, this));
82 add_item(key_copy = new KeyframePopupCopy(mwindow, this));
84 key_edit = new KeyframePopupEdit(mwindow, this);
85 key_mbar = new BC_MenuItem("-");
86 key_smooth = new KeyframePopupCurveMode(mwindow, this, FloatAuto::SMOOTH);
87 key_linear = new KeyframePopupCurveMode(mwindow, this, FloatAuto::LINEAR);
88 key_free_t = new KeyframePopupCurveMode(mwindow, this, FloatAuto::TFREE );
89 key_free = new KeyframePopupCurveMode(mwindow, this, FloatAuto::FREE );
92 int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
94 this->keyframe_plugin = plugin;
95 this->keyframe_auto = keyframe;
96 this->keyframe_autos = 0;
97 this->keyframe_automation = 0;
98 handle_curve_mode(0, 0);
102 int KeyframePopup::update(Automation *automation, Autos *autos, Auto *auto_keyframe)
104 this->keyframe_plugin = 0;
105 this->keyframe_automation = automation;
106 this->keyframe_autos = autos;
107 this->keyframe_auto = auto_keyframe;
108 handle_curve_mode(autos, auto_keyframe);
111 double current_position = mwindow->edl->local_session->get_selectionstart(1);
112 double new_position = keyframe_automation->track->from_units(keyframe_auto->position);
113 mwindow->edl->local_session->set_selectionstart(new_position);
114 mwindow->edl->local_session->set_selectionend(new_position);
115 if (current_position != new_position)
117 mwindow->edl->local_session->set_selectionstart(new_position);
118 mwindow->edl->local_session->set_selectionend(new_position);
119 mwindow->gui->lock_window();
120 mwindow->gui->update(1, 1, 1, 1, 1, 1, 0);
121 mwindow->gui->unlock_window();
126 void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
127 // determines the type of automation node. if floatauto, adds
128 // menu entries showing the curve mode of the node
130 if( !key_edit_displayed && keyframe_plugin ) {
132 key_edit_displayed = true;
134 else if( key_edit_displayed && !keyframe_plugin ) {
135 remove_item(key_mbar);
136 key_edit_displayed = false;
139 if(!key_mode_displayed && autos && autos->get_type() == AUTOMATION_TYPE_FLOAT)
140 { // append additional menu entries showing the curve_mode
142 add_item(key_smooth);
143 add_item(key_linear);
144 add_item(key_free_t);
146 key_mode_displayed = true;
148 else if(key_mode_displayed && (!autos || autos->get_type() != AUTOMATION_TYPE_FLOAT))
149 { // remove additional menu entries
150 remove_item(key_free);
151 remove_item(key_free_t);
152 remove_item(key_linear);
153 remove_item(key_smooth);
154 remove_item(key_mbar);
155 key_mode_displayed = false;
157 if(key_mode_displayed && auto_keyframe)
158 { // set checkmarks to display current mode
159 key_smooth->toggle_mode((FloatAuto*)auto_keyframe);
160 key_linear->toggle_mode((FloatAuto*)auto_keyframe);
161 key_free_t->toggle_mode((FloatAuto*)auto_keyframe);
162 key_free ->toggle_mode((FloatAuto*)auto_keyframe);
166 KeyframePopupDelete::KeyframePopupDelete(MWindow *mwindow, KeyframePopup *popup)
167 : BC_MenuItem(_("Delete keyframe"))
169 this->mwindow = mwindow;
173 KeyframePopupDelete::~KeyframePopupDelete()
177 int KeyframePopupDelete::handle_event()
179 mwindow->undo->update_undo_before(_("delete keyframe"), 0);
180 delete popup->keyframe_auto;
181 mwindow->undo->update_undo_after(_("delete keyframe"), LOAD_ALL);
183 mwindow->save_backup();
184 mwindow->gui->update(0, 1, // 1 for incremental drawing. 2 for full refresh
186 mwindow->update_plugin_guis();
187 mwindow->restart_brender();
188 mwindow->sync_parameters(CHANGE_EDL);
193 KeyframePopupShow::KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup)
194 : BC_MenuItem(_("Show keyframe settings"))
196 this->mwindow = mwindow;
200 KeyframePopupShow::~KeyframePopupShow()
204 int KeyframePopupShow::handle_event()
206 if (popup->keyframe_plugin)
208 mwindow->update_plugin_guis();
209 mwindow->show_plugin(popup->keyframe_plugin);
211 else if( popup->keyframe_automation ) {
214 mwindow->cwindow->gui->lock_window();
216 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos ||
217 popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
220 mwindow->cwindow->gui->set_operation(CWINDOW_PROJECTOR);
222 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos ||
223 popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
226 mwindow->cwindow->gui->set_operation(CWINDOW_CAMERA);
228 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
231 // no window to be shown
233 // first find the appropriate patchgui
234 PatchBay *patchbay = mwindow->gui->patchbay;
235 PatchGUI *patchgui = 0;
236 for (int i = 0; i < patchbay->patches.total; i++)
237 if (patchbay->patches.values[i]->track == popup->keyframe_automation->track)
238 patchgui = patchbay->patches.values[i];
241 // FIXME: repositioning of the listbox needs support in guicast
242 // int cursor_x = popup->get_relative_cursor_x();
243 // int cursor_y = popup->get_relative_cursor_y();
244 // vpatchgui->mode->reposition_window(cursor_x, cursor_y);
247 // Open the popup menu
248 VPatchGUI *vpatchgui = (VPatchGUI *)patchgui;
249 vpatchgui->mode->activate_menu();
252 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
255 mwindow->cwindow->gui->set_operation(CWINDOW_MASK);
257 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
260 // no window to be shown
262 // first find the appropriate patchgui
263 PatchBay *patchbay = mwindow->gui->patchbay;
264 PatchGUI *patchgui = 0;
265 for (int i = 0; i < patchbay->patches.total; i++)
266 if (patchbay->patches.values[i]->track == popup->keyframe_automation->track)
267 patchgui = patchbay->patches.values[i];
270 // Open the popup menu at current mouse position
271 APatchGUI *apatchgui = (APatchGUI *)patchgui;
272 int cursor_x = popup->get_relative_cursor_x();
273 int cursor_y = popup->get_relative_cursor_y();
274 apatchgui->pan->activate(cursor_x, cursor_y);
279 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
282 // no window to be shown, so do nothing
283 // IDEA: open window for fading
286 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
289 // no window to be shown, so do nothing
290 // IDEA: directly switch
295 // ensure bringing to front
298 ((CPanelToolWindow *)(mwindow->cwindow->gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]))->set_shown(0);
299 ((CPanelToolWindow *)(mwindow->cwindow->gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]))->set_shown(1);
301 mwindow->cwindow->gui->unlock_window();
311 KeyframePopupCopy::KeyframePopupCopy(MWindow *mwindow, KeyframePopup *popup)
312 : BC_MenuItem(_("Copy keyframe"))
314 this->mwindow = mwindow;
318 KeyframePopupCopy::~KeyframePopupCopy()
322 int KeyframePopupCopy::handle_event()
326 we want to copy just keyframe under cursor, NOT all keyframes at this frame
327 - very hard to do, so this is good approximation for now...
331 if (popup->keyframe_automation)
334 EDL *edl = mwindow->edl;
335 Track *track = popup->keyframe_automation->track;
336 int64_t position = popup->keyframe_auto->position;
338 // first find out type of our auto
340 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos)
341 autoconf.projector = 1;
342 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
344 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos)
346 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
348 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
350 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
352 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
354 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
356 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
360 // now create a clipboard
361 file.tag.set_title("AUTO_CLIPBOARD");
362 file.tag.set_property("LENGTH", 0);
363 file.tag.set_property("FRAMERATE", edl->session->frame_rate);
364 file.tag.set_property("SAMPLERATE", edl->session->sample_rate);
366 file.append_newline();
367 file.append_newline();
369 /* track->copy_automation(position,
375 file.tag.set_title("TRACK");
377 track->save_header(&file);
379 file.append_newline();
381 track->automation->copy(position,
390 file.tag.set_title("/TRACK");
392 file.append_newline();
393 file.append_newline();
394 file.append_newline();
395 file.append_newline();
399 file.tag.set_title("/AUTO_CLIPBOARD");
401 file.append_newline();
402 file.terminate_string();
404 mwindow->gui->lock_window();
405 mwindow->gui->get_clipboard()->to_clipboard(file.string,
407 SECONDARY_SELECTION);
408 mwindow->gui->unlock_window();
412 mwindow->copy_automation();
418 KeyframePopupCurveMode::KeyframePopupCurveMode(
420 KeyframePopup *popup,
422 : BC_MenuItem( get_labeltext(curve_mode))
424 this->curve_mode = curve_mode;
425 this->mwindow = mwindow;
429 KeyframePopupCurveMode::~KeyframePopupCurveMode() { }
432 const char* KeyframePopupCurveMode::get_labeltext(int mode)
435 case FloatAuto::SMOOTH: return _("smooth curve");
436 case FloatAuto::LINEAR: return _("linear segments");
437 case FloatAuto::TFREE: return _("tangent edit");
438 case FloatAuto::FREE: return _("disjoint edit");
440 return "misconfigured";
444 void KeyframePopupCurveMode::toggle_mode(FloatAuto *keyframe)
446 set_checked(curve_mode == keyframe->curve_mode);
450 int KeyframePopupCurveMode::handle_event()
452 if (popup->keyframe_autos &&
453 popup->keyframe_autos->get_type() == AUTOMATION_TYPE_FLOAT)
455 mwindow->undo->update_undo_before(_("change keyframe curve mode"), 0);
456 ((FloatAuto*)popup->keyframe_auto)->
457 change_curve_mode((FloatAuto::t_mode)curve_mode);
459 // if we switched to some "auto" mode, this may imply a
460 // real change to parameters, so this needs to be undoable...
461 mwindow->undo->update_undo_after(_("change keyframe curve mode"), LOAD_ALL);
462 mwindow->save_backup();
464 mwindow->gui->update(0, 1, 0,0,0,0,0); // incremental redraw for canvas
465 mwindow->cwindow->update(0,0, 1, 0,0); // redraw tool window in compositor
466 mwindow->update_plugin_guis();
467 mwindow->restart_brender();
468 mwindow->sync_parameters(CHANGE_EDL);
474 KeyframePopupEdit::KeyframePopupEdit(MWindow *mwindow, KeyframePopup *popup)
475 : BC_MenuItem(_("Edit Params..."))
477 this->mwindow = mwindow;
481 int KeyframePopupEdit::handle_event()
483 mwindow->show_keyframe_gui(popup->keyframe_plugin);
488 KeyframeHidePopup::KeyframeHidePopup(MWindow *mwindow, MWindowGUI *gui)
489 : BC_PopupMenu(0, 0, 0, "", 0)
491 this->mwindow = mwindow;
493 this->keyframe_autos = 0;
496 KeyframeHidePopup::~KeyframeHidePopup()
500 void KeyframeHidePopup::create_objects()
502 add_item(new KeyframePopupHide(mwindow, this));
505 int KeyframeHidePopup::update(Autos *autos)
507 this->keyframe_autos = autos;
511 KeyframePopupHide::KeyframePopupHide(MWindow *mwindow, KeyframeHidePopup *popup)
512 : BC_MenuItem(_("Hide keyframe type"))
514 this->mwindow = mwindow;
518 int KeyframePopupHide::handle_event()
520 // Get the array index of the curve
522 if(popup->keyframe_autos)
524 if(popup->keyframe_autos->type == Autos::AUTOMATION_TYPE_PLUGIN)
526 mwindow->edl->session->auto_conf->plugins = 0;
531 Track *track = popup->keyframe_autos->track;
534 Automation *automation = track->automation;
537 for(int i = 0; i < AUTOMATION_TOTAL; i++)
539 if(automation->autos[i] == popup->keyframe_autos)
541 mwindow->edl->session->auto_conf->autos[i] = 0;
553 mwindow->gui->update(0,
554 1, // 1 for incremental drawing. 2 for full refresh
560 mwindow->gui->mainmenu->update_toggles(1);
561 mwindow->gui->unlock_window();
562 mwindow->gwindow->gui->update_toggles(1);
563 mwindow->gui->lock_window("KeyframePopupHide::handle_event");