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
25 #include "keyframepopup.h"
29 #include "mwindowgui.h"
30 #include "localsession.h"
31 #include "cwindowgui.h"
35 #include "apatchgui.h"
36 #include "vpatchgui.h"
38 #include "maincursor.h"
39 #include "bcwindowbase.h"
41 #include "edlsession.h"
44 KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
45 : BC_PopupMenu(0, 0, 0, "", 0)
47 this->mwindow = mwindow;
56 key_mode_displayed = false;
57 key_edit_displayed = false;
60 KeyframePopup::~KeyframePopup()
62 if( !key_mode_displayed ) {
69 if( !key_edit_displayed ) {
74 void KeyframePopup::create_objects()
76 add_item(key_show = new KeyframePopupShow(mwindow, this));
77 add_item(key_delete = new KeyframePopupDelete(mwindow, this));
78 add_item(key_copy = new KeyframePopupCopy(mwindow, this));
80 key_edit = new KeyframePopupEdit(mwindow, this);
81 key_mbar = new BC_MenuItem("-");
82 key_smooth = new KeyframePopupCurveMode(mwindow, this, FloatAuto::SMOOTH);
83 key_linear = new KeyframePopupCurveMode(mwindow, this, FloatAuto::LINEAR);
84 key_free_t = new KeyframePopupCurveMode(mwindow, this, FloatAuto::TFREE );
85 key_free = new KeyframePopupCurveMode(mwindow, this, FloatAuto::FREE );
88 int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
90 this->keyframe_plugin = plugin;
91 this->keyframe_auto = keyframe;
92 this->keyframe_autos = 0;
93 this->keyframe_automation = 0;
94 handle_curve_mode(0, 0);
98 int KeyframePopup::update(Automation *automation, Autos *autos, Auto *auto_keyframe)
100 this->keyframe_plugin = 0;
101 this->keyframe_automation = automation;
102 this->keyframe_autos = autos;
103 this->keyframe_auto = auto_keyframe;
104 handle_curve_mode(autos, auto_keyframe);
107 double current_position = mwindow->edl->local_session->get_selectionstart(1);
108 double new_position = keyframe_automation->track->from_units(keyframe_auto->position);
109 mwindow->edl->local_session->set_selectionstart(new_position);
110 mwindow->edl->local_session->set_selectionend(new_position);
111 if (current_position != new_position)
113 mwindow->edl->local_session->set_selectionstart(new_position);
114 mwindow->edl->local_session->set_selectionend(new_position);
115 mwindow->gui->lock_window();
116 mwindow->gui->update(1, 1, 1, 1, 1, 1, 0);
117 mwindow->gui->unlock_window();
122 void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
123 // determines the type of automation node. if floatauto, adds
124 // menu entries showing the curve mode of the node
126 if( !key_edit_displayed && keyframe_plugin ) {
128 key_edit_displayed = true;
130 else if( key_edit_displayed && !keyframe_plugin ) {
131 remove_item(key_mbar);
132 key_edit_displayed = false;
135 if(!key_mode_displayed && autos && autos->get_type() == AUTOMATION_TYPE_FLOAT)
136 { // append additional menu entries showing the curve_mode
138 add_item(key_smooth);
139 add_item(key_linear);
140 add_item(key_free_t);
142 key_mode_displayed = true;
144 else if(key_mode_displayed && (!autos || autos->get_type() != AUTOMATION_TYPE_FLOAT))
145 { // remove additional menu entries
146 remove_item(key_free);
147 remove_item(key_free_t);
148 remove_item(key_linear);
149 remove_item(key_smooth);
150 remove_item(key_mbar);
151 key_mode_displayed = false;
153 if(key_mode_displayed && auto_keyframe)
154 { // set checkmarks to display current mode
155 key_smooth->toggle_mode((FloatAuto*)auto_keyframe);
156 key_linear->toggle_mode((FloatAuto*)auto_keyframe);
157 key_free_t->toggle_mode((FloatAuto*)auto_keyframe);
158 key_free ->toggle_mode((FloatAuto*)auto_keyframe);
162 KeyframePopupDelete::KeyframePopupDelete(MWindow *mwindow, KeyframePopup *popup)
163 : BC_MenuItem(_("Delete keyframe"))
165 this->mwindow = mwindow;
169 KeyframePopupDelete::~KeyframePopupDelete()
173 int KeyframePopupDelete::handle_event()
175 mwindow->undo->update_undo_before(_("delete keyframe"), 0);
176 delete popup->keyframe_auto;
177 mwindow->undo->update_undo_after(_("delete keyframe"), LOAD_ALL);
179 mwindow->save_backup();
180 mwindow->gui->update(0, 1, // 1 for incremental drawing. 2 for full refresh
182 mwindow->update_plugin_guis();
183 mwindow->restart_brender();
184 mwindow->sync_parameters(CHANGE_EDL);
189 KeyframePopupShow::KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup)
190 : BC_MenuItem(_("Show keyframe settings"))
192 this->mwindow = mwindow;
196 KeyframePopupShow::~KeyframePopupShow()
200 int KeyframePopupShow::handle_event()
202 if (popup->keyframe_plugin)
204 mwindow->update_plugin_guis();
205 mwindow->show_plugin(popup->keyframe_plugin);
207 else if( popup->keyframe_automation ) {
210 mwindow->cwindow->gui->lock_window();
212 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos ||
213 popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
216 mwindow->cwindow->gui->set_operation(CWINDOW_PROJECTOR);
218 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos ||
219 popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
222 mwindow->cwindow->gui->set_operation(CWINDOW_CAMERA);
224 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
227 // no window to be shown
229 // first find the appropriate patchgui
230 PatchBay *patchbay = mwindow->gui->patchbay;
231 PatchGUI *patchgui = 0;
232 for (int i = 0; i < patchbay->patches.total; i++)
233 if (patchbay->patches.values[i]->track == popup->keyframe_automation->track)
234 patchgui = patchbay->patches.values[i];
237 // FIXME: repositioning of the listbox needs support in guicast
238 // int cursor_x = popup->get_relative_cursor_x();
239 // int cursor_y = popup->get_relative_cursor_y();
240 // vpatchgui->mode->reposition_window(cursor_x, cursor_y);
243 // Open the popup menu
244 VPatchGUI *vpatchgui = (VPatchGUI *)patchgui;
245 vpatchgui->mode->activate_menu();
248 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
251 mwindow->cwindow->gui->set_operation(CWINDOW_MASK);
253 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
256 // no window to be shown
258 // first find the appropriate patchgui
259 PatchBay *patchbay = mwindow->gui->patchbay;
260 PatchGUI *patchgui = 0;
261 for (int i = 0; i < patchbay->patches.total; i++)
262 if (patchbay->patches.values[i]->track == popup->keyframe_automation->track)
263 patchgui = patchbay->patches.values[i];
266 // Open the popup menu at current mouse position
267 APatchGUI *apatchgui = (APatchGUI *)patchgui;
268 int cursor_x = popup->get_relative_cursor_x();
269 int cursor_y = popup->get_relative_cursor_y();
270 apatchgui->pan->activate(cursor_x, cursor_y);
275 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
278 // no window to be shown, so do nothing
279 // IDEA: open window for fading
282 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
285 // no window to be shown, so do nothing
286 // IDEA: directly switch
291 // ensure bringing to front
294 ((CPanelToolWindow *)(mwindow->cwindow->gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]))->set_shown(0);
295 ((CPanelToolWindow *)(mwindow->cwindow->gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]))->set_shown(1);
297 mwindow->cwindow->gui->unlock_window();
307 KeyframePopupCopy::KeyframePopupCopy(MWindow *mwindow, KeyframePopup *popup)
308 : BC_MenuItem(_("Copy keyframe"))
310 this->mwindow = mwindow;
314 KeyframePopupCopy::~KeyframePopupCopy()
318 int KeyframePopupCopy::handle_event()
322 we want to copy just keyframe under cursor, NOT all keyframes at this frame
323 - very hard to do, so this is good approximation for now...
327 if (popup->keyframe_automation)
330 EDL *edl = mwindow->edl;
331 Track *track = popup->keyframe_automation->track;
332 int64_t position = popup->keyframe_auto->position;
334 // first find out type of our auto
336 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos)
337 autoconf.projector = 1;
338 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
340 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos)
342 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
344 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
346 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
348 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
350 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
352 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
356 // now create a clipboard
357 file.tag.set_title("AUTO_CLIPBOARD");
358 file.tag.set_property("LENGTH", 0);
359 file.tag.set_property("FRAMERATE", edl->session->frame_rate);
360 file.tag.set_property("SAMPLERATE", edl->session->sample_rate);
362 file.append_newline();
363 file.append_newline();
365 /* track->copy_automation(position,
371 file.tag.set_title("TRACK");
373 track->save_header(&file);
375 file.append_newline();
377 track->automation->copy(position,
386 file.tag.set_title("/TRACK");
388 file.append_newline();
389 file.append_newline();
390 file.append_newline();
391 file.append_newline();
395 file.tag.set_title("/AUTO_CLIPBOARD");
397 file.append_newline();
398 file.terminate_string();
400 mwindow->gui->lock_window();
401 mwindow->gui->get_clipboard()->to_clipboard(file.string,
403 SECONDARY_SELECTION);
404 mwindow->gui->unlock_window();
408 mwindow->copy_automation();
414 KeyframePopupCurveMode::KeyframePopupCurveMode(
416 KeyframePopup *popup,
418 : BC_MenuItem( get_labeltext(curve_mode))
420 this->curve_mode = curve_mode;
421 this->mwindow = mwindow;
425 KeyframePopupCurveMode::~KeyframePopupCurveMode() { }
428 const char* KeyframePopupCurveMode::get_labeltext(int mode)
431 case FloatAuto::SMOOTH: return _("smooth curve");
432 case FloatAuto::LINEAR: return _("linear segments");
433 case FloatAuto::TFREE: return _("tangent edit");
434 case FloatAuto::FREE: return _("disjoint edit");
436 return "misconfigured";
440 void KeyframePopupCurveMode::toggle_mode(FloatAuto *keyframe)
442 set_checked(curve_mode == keyframe->curve_mode);
446 int KeyframePopupCurveMode::handle_event()
448 if (popup->keyframe_autos &&
449 popup->keyframe_autos->get_type() == AUTOMATION_TYPE_FLOAT)
451 mwindow->undo->update_undo_before(_("change keyframe curve mode"), 0);
452 ((FloatAuto*)popup->keyframe_auto)->
453 change_curve_mode((FloatAuto::t_mode)curve_mode);
455 // if we switched to some "auto" mode, this may imply a
456 // real change to parameters, so this needs to be undoable...
457 mwindow->undo->update_undo_after(_("change keyframe curve mode"), LOAD_ALL);
458 mwindow->save_backup();
460 mwindow->gui->update(0, 1, 0,0,0,0,0); // incremental redraw for canvas
461 mwindow->cwindow->update(0,0, 1, 0,0); // redraw tool window in compositor
462 mwindow->update_plugin_guis();
463 mwindow->restart_brender();
464 mwindow->sync_parameters(CHANGE_EDL);
470 KeyframePopupEdit::KeyframePopupEdit(MWindow *mwindow, KeyframePopup *popup)
471 : BC_MenuItem(_("Edit Params..."))
473 this->mwindow = mwindow;
477 int KeyframePopupEdit::handle_event()
479 mwindow->show_keyframe_gui(popup->keyframe_plugin);