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
23 #include "bcsignals.h"
26 #include "keyframes.h"
27 #include "keyframegui.h"
30 #include "localsession.h"
31 #include "mainsession.h"
34 #include "mwindowgui.h"
38 #include "trackcanvas.h"
44 KeyFrameThread::KeyFrameThread(MWindow *mwindow)
47 this->mwindow = mwindow;
50 keyframe_data = new ArrayList<BC_ListBoxItem*>[KEYFRAME_COLUMNS];
53 column_titles[0] = (char*)_("Parameter");
54 column_titles[1] = (char*)_("Value");
57 presets_data = new ArrayList<BC_ListBoxItem*>;
58 presets_db = new PresetsDB;
61 KeyFrameThread::~KeyFrameThread()
64 for(int i = 0; i < KEYFRAME_COLUMNS; i++)
65 keyframe_data[i].remove_all_objects();
66 delete [] keyframe_data;
67 presets_data->remove_all_objects();
73 void KeyFrameThread::update_values()
75 // Get the current selection before deleting the tables
77 for(int i = 0; i < keyframe_data[0].size(); i++)
79 if(keyframe_data[0].get(i)->get_selected())
86 for(int i = 0; i < KEYFRAME_COLUMNS; i++)
87 keyframe_data[i].remove_all_objects();
90 // Must lock main window to read keyframe
91 mwindow->gui->lock_window("KeyFrameThread::update_values");
92 if(!plugin || !mwindow->edl->tracks->plugin_exists(plugin))
94 mwindow->gui->unlock_window();
98 KeyFrame *keyframe = 0;
99 if(this->keyframe && plugin->keyframe_exists(this->keyframe))
101 // If user edited a specific keyframe, use it.
102 keyframe = this->keyframe;
107 // Use currently highlighted keyframe
108 keyframe = plugin->get_prev_keyframe(
109 plugin->track->to_units(
110 mwindow->edl->local_session->get_selectionstart(1), 0),
117 char *text = 0, *extra = 0;
118 keyframe->get_contents(&hash, &text, &extra);
120 for(int i = 0; i < hash.size(); i++)
122 keyframe_data[0].append(new BC_ListBoxItem(hash.get_key(i)));
123 keyframe_data[1].append(new BC_ListBoxItem(hash.get_value(i)));
125 keyframe_data[0].append(new BC_ListBoxItem((char*)_("TEXT")));
126 keyframe_data[1].append(new BC_ListBoxItem(text));
132 column_width[0] = mwindow->session->keyframedialog_column1;
133 column_width[1] = mwindow->session->keyframedialog_column2;
134 if(selection >= 0 && selection < keyframe_data[0].size())
136 for(int i = 0; i < KEYFRAME_COLUMNS; i++)
137 keyframe_data[i].get(selection)->set_selected(1);
139 mwindow->gui->unlock_window();
144 void KeyFrameThread::start_window(Plugin *plugin, KeyFrame *keyframe)
147 if(!BC_DialogThread::is_running())
149 if(!mwindow->edl->tracks->plugin_exists(plugin)) return;
150 this->keyframe = keyframe;
151 this->plugin = plugin;
152 plugin->calculate_title(plugin_title, 0);
153 sprintf(window_title, _(PROGRAM_NAME ": %s Keyframe"), plugin_title);
155 calculate_preset_list();
160 mwindow->gui->unlock_window();
161 BC_DialogThread::start();
162 mwindow->gui->lock_window("KeyFrameThread::start_window");
166 BC_DialogThread::start();
170 BC_Window* KeyFrameThread::new_gui()
172 mwindow->gui->lock_window("KeyFrameThread::new_gui");
174 int x = mwindow->gui->get_abs_cursor_x(0) -
175 mwindow->session->plugindialog_w / 2;
176 int y = mwindow->gui->get_abs_cursor_y(0) -
177 mwindow->session->plugindialog_h / 2;
179 KeyFrameWindow *window = new KeyFrameWindow(mwindow,
185 window->create_objects();
188 mwindow->gui->unlock_window();
193 void KeyFrameThread::handle_done_event(int result)
198 const char *title = ((KeyFrameWindow*)get_gui())->preset_text->get_text();
204 void KeyFrameThread::handle_close_event(int result)
212 void KeyFrameThread::calculate_preset_list()
214 presets_data->remove_all_objects();
215 int total_presets = presets_db->get_total_presets(plugin_title);
216 for(int i = 0; i < total_presets; i++)
218 presets_data->append(new BC_ListBoxItem(presets_db->get_preset_title(
225 void KeyFrameThread::update_gui(int update_value_text)
228 if(BC_DialogThread::is_running())
230 mwindow->gui->lock_window("KeyFrameThread::update_gui");
232 mwindow->gui->unlock_window();
234 lock_window("KeyFrameThread::update_gui");
235 KeyFrameWindow *window = (KeyFrameWindow*)get_gui();
238 window->lock_window("KeyFrameThread::update_gui");
239 window->keyframe_list->update(keyframe_data,
240 (const char **)column_titles,
243 window->keyframe_list->get_xposition(),
244 window->keyframe_list->get_yposition(),
245 window->keyframe_list->get_highlighted_item());
246 if( update_value_text )
248 int selection_number = window->keyframe_list->get_selection_number(0, 0);
249 if( selection_number >= 0 && selection_number < keyframe_data[1].size())
251 char *edit_value = keyframe_data[1].get(selection_number)->get_text();
252 window->value_text->update(edit_value);
255 window->unlock_window();
262 void KeyFrameThread::save_preset(const char *title)
264 get_gui()->unlock_window();
265 mwindow->gui->lock_window("KeyFrameThread::save_preset");
267 // Test EDL for plugin existence
268 if(!mwindow->edl->tracks->plugin_exists(plugin))
270 mwindow->gui->unlock_window();
271 get_gui()->lock_window("KeyFrameThread::save_preset 2");
276 // Get current plugin keyframe
277 EDL *edl = mwindow->edl;
278 Track *track = plugin->track;
279 KeyFrame *keyframe = plugin->get_prev_keyframe(
280 track->to_units(edl->local_session->get_selectionstart(1), 0),
284 presets_db->save_preset(plugin_title, title, keyframe->get_data());
286 mwindow->gui->unlock_window();
287 get_gui()->lock_window("KeyFrameThread::save_preset 2");
291 calculate_preset_list();
292 ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data,
298 void KeyFrameThread::delete_preset(const char *title)
300 get_gui()->unlock_window();
301 mwindow->gui->lock_window("KeyFrameThread::save_preset");
303 // Test EDL for plugin existence
304 if(!mwindow->edl->tracks->plugin_exists(plugin))
306 mwindow->gui->unlock_window();
307 get_gui()->lock_window("KeyFrameThread::delete_preset 1");
311 presets_db->delete_preset(plugin_title, title);
313 mwindow->gui->unlock_window();
314 get_gui()->lock_window("KeyFrameThread::delete_preset 2");
318 calculate_preset_list();
319 ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data,
326 void KeyFrameThread::apply_preset(const char *title)
328 if(presets_db->preset_exists(plugin_title, title))
330 get_gui()->unlock_window();
331 mwindow->gui->lock_window("KeyFrameThread::apply_preset");
333 // Test EDL for plugin existence
334 if(!mwindow->edl->tracks->plugin_exists(plugin))
336 mwindow->gui->unlock_window();
337 get_gui()->lock_window("KeyFrameThread::delete_preset 1");
341 mwindow->undo->update_undo_before();
344 #ifdef USE_KEYFRAME_SPANNING
346 presets_db->load_preset(plugin_title, title, &keyframe);
347 plugin->keyframes->update_parameter(&keyframe);
349 KeyFrame *keyframe = plugin->get_keyframe();
350 presets_db->load_preset(plugin_title, title, keyframe);
352 mwindow->save_backup();
353 mwindow->undo->update_undo_after(_("apply preset"), LOAD_AUTOMATION);
355 mwindow->update_plugin_guis(0);
356 mwindow->gui->draw_overlays(1);
357 mwindow->sync_parameters(CHANGE_PARAMS);
361 mwindow->gui->unlock_window();
362 get_gui()->lock_window("KeyFrameThread::apply_preset");
367 void KeyFrameThread::apply_value()
369 const char *text = 0;
371 KeyFrameWindow *window = (KeyFrameWindow*)get_gui();
372 int selection = window->keyframe_list->get_selection_number(0, 0);
373 //printf("KeyFrameThread::apply_value %d %d\n", __LINE__, selection);
374 if(selection < 0) return;
376 if(selection == keyframe_data[0].size() - 1)
377 text = window->value_text->get_text();
380 char *key = keyframe_data[0].get(selection)->get_text();
381 const char *value = window->value_text->get_text();
382 hash.update(key, value);
385 get_gui()->unlock_window();
386 mwindow->gui->lock_window("KeyFrameThread::apply_value");
387 if(plugin && mwindow->edl->tracks->plugin_exists(plugin))
389 mwindow->undo->update_undo_before();
390 if(mwindow->session->keyframedialog_all)
392 // Search for all keyframes in selection but don't create a new one.
393 Track *track = plugin->track;
394 int64_t start = track->to_units(mwindow->edl->local_session->get_selectionstart(0), 0);
395 int64_t end = track->to_units(mwindow->edl->local_session->get_selectionend(0), 0);
397 for(KeyFrame *current = (KeyFrame*)plugin->keyframes->last;
399 current = (KeyFrame*)PREVIOUS)
402 if(current && current->position < end)
404 current->update_parameter(&hash, text, 0);
405 // Stop at beginning of range
406 if(current->position <= start) break;
412 KeyFrame* keyframe = (KeyFrame*)plugin->keyframes->default_auto;
413 keyframe->update_parameter(&hash, text, 0);
418 // Create new keyframe if enabled
419 KeyFrame *keyframe = plugin->get_keyframe();
420 keyframe->update_parameter(&hash, text, 0);
425 printf("KeyFrameThread::apply_value %d: plugin doesn't exist\n", __LINE__);
428 mwindow->save_backup();
429 mwindow->undo->update_undo_after(_("edit keyframe"), LOAD_AUTOMATION);
431 mwindow->update_plugin_guis(0);
432 mwindow->gui->draw_overlays(1);
433 mwindow->sync_parameters(CHANGE_PARAMS);
437 mwindow->gui->unlock_window();
441 get_gui()->lock_window("KeyFrameThread::apply_value");
447 KeyFrameWindow::KeyFrameWindow(MWindow *mwindow,
448 KeyFrameThread *thread,
452 : BC_Window(title_string,
455 mwindow->session->keyframedialog_w,
456 mwindow->session->keyframedialog_h,
463 this->mwindow = mwindow;
464 this->thread = thread;
467 void KeyFrameWindow::create_objects()
469 Theme *theme = mwindow->theme;
471 theme->get_keyframedialog_sizes(this);
472 thread->column_width[0] = mwindow->session->keyframedialog_column1;
473 thread->column_width[1] = mwindow->session->keyframedialog_column2;
474 lock_window("KeyFrameWindow::create_objects");
479 add_subwindow(title1 = new BC_Title(theme->keyframe_list_x,
480 theme->keyframe_list_y -
481 BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) -
482 theme->widget_border,
483 _("Keyframe parameters:"),
485 add_subwindow(keyframe_list = new KeyFrameList(thread,
487 theme->keyframe_list_x,
488 theme->keyframe_list_y,
489 theme->keyframe_list_w,
490 theme->keyframe_list_h));
491 // add_subwindow(title2 = new BC_Title(theme->keyframe_text_x,
492 // theme->keyframe_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border,
493 // _("Global Text:")));
494 // add_subwindow(keyframe_text = new KeyFrameText(thread,
496 // theme->keyframe_text_x,
497 // theme->keyframe_text_y,
498 // theme->keyframe_text_w));
499 add_subwindow(title3 = new BC_Title(theme->keyframe_value_x,
500 theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border,
502 add_subwindow(value_text = new KeyFrameValue(thread,
504 theme->keyframe_value_x,
505 theme->keyframe_value_y,
506 theme->keyframe_value_w));
507 add_subwindow(all_toggle = new KeyFrameAll(thread,
509 theme->keyframe_all_x,
510 theme->keyframe_all_y));
516 add_subwindow(title4 = new BC_Title(theme->presets_list_x,
517 theme->presets_list_y -
518 BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) -
519 theme->widget_border,
522 add_subwindow(preset_list = new KeyFramePresetsList(thread,
524 theme->presets_list_x,
525 theme->presets_list_y,
526 theme->presets_list_w,
527 theme->presets_list_h));
528 add_subwindow(title5 = new BC_Title(theme->presets_text_x,
529 theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border,
530 _("Preset title:")));
531 add_subwindow(preset_text = new KeyFramePresetsText(thread,
533 theme->presets_text_x,
534 theme->presets_text_y,
535 theme->presets_text_w));
536 add_subwindow(delete_preset = new KeyFramePresetsDelete(thread,
538 theme->presets_delete_x,
539 theme->presets_delete_y));
540 add_subwindow(save_preset = new KeyFramePresetsSave(thread,
542 theme->presets_save_x,
543 theme->presets_save_y));
544 add_subwindow(apply_preset = new KeyFramePresetsApply(thread,
546 theme->presets_apply_x,
547 theme->presets_apply_y));
552 add_subwindow(new KeyFramePresetsOK(thread, this));
553 add_subwindow(new BC_CancelButton(this));
559 int KeyFrameWindow::resize_event(int w, int h)
561 Theme *theme = mwindow->theme;
562 mwindow->session->keyframedialog_w = w;
563 mwindow->session->keyframedialog_h = h;
564 theme->get_keyframedialog_sizes(this);
568 title1->reposition_window(theme->keyframe_list_x,
569 theme->keyframe_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
570 // title2->reposition_window(theme->keyframe_text_x,
571 // theme->keyframe_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
572 title3->reposition_window(theme->keyframe_value_x,
573 theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
574 keyframe_list->reposition_window(theme->keyframe_list_x,
575 theme->keyframe_list_y,
576 theme->keyframe_list_w,
577 theme->keyframe_list_h);
578 // text->reposition_window(theme->keyframe_text_x,
579 // theme->keyframe_text_y,
580 // theme->keyframe_text_w);
581 value_text->reposition_window(theme->keyframe_value_x,
582 theme->keyframe_value_y,
583 theme->keyframe_value_w);
584 all_toggle->reposition_window(theme->keyframe_all_x,
585 theme->keyframe_all_y);
587 #endif // EDIT_KEYFRAME
592 title4->reposition_window(theme->presets_list_x,
593 theme->presets_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
594 title5->reposition_window(theme->presets_text_x,
595 theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
596 preset_list->reposition_window(theme->presets_list_x,
597 theme->presets_list_y,
598 theme->presets_list_w,
599 theme->presets_list_h);
600 preset_text->reposition_window(theme->presets_text_x,
601 theme->presets_text_y,
602 theme->presets_text_w);
603 delete_preset->reposition_window(theme->presets_delete_x,
604 theme->presets_delete_y);
605 save_preset->reposition_window(theme->presets_save_x,
606 theme->presets_save_y);
607 apply_preset->reposition_window(theme->presets_apply_x,
608 theme->presets_apply_y);
619 KeyFrameList::KeyFrameList(KeyFrameThread *thread,
620 KeyFrameWindow *window,
630 thread->keyframe_data,
631 (const char **)thread->column_titles,
632 thread->column_width,
635 this->thread = thread;
636 this->window = window;
639 int KeyFrameList::selection_changed()
641 window->value_text->update(
642 thread->keyframe_data[1].get(get_selection_number(0, 0))->get_text());
646 int KeyFrameList::handle_event()
652 int KeyFrameList::column_resize_event()
654 thread->mwindow->session->keyframedialog_column1 = get_column_width(0);
655 thread->mwindow->session->keyframedialog_column2 = get_column_width(1);
662 // KeyFrameText::KeyFrameText(KeyFrameThread *thread,
663 // KeyFrameWindow *window,
673 // this->thread = thread;
674 // this->window = window;
677 // int KeyFrameText::handle_event()
684 KeyFrameValue::KeyFrameValue(KeyFrameThread *thread,
685 KeyFrameWindow *window,
695 this->thread = thread;
696 this->window = window;
699 int KeyFrameValue::handle_event()
701 thread->update_values();
709 KeyFrameAll::KeyFrameAll(KeyFrameThread *thread,
710 KeyFrameWindow *window,
715 thread->mwindow->session->keyframedialog_all,
716 _("Apply to all selected keyframes"))
718 this->thread = thread;
719 this->window = window;
722 int KeyFrameAll::handle_event()
724 thread->mwindow->session->keyframedialog_all = get_value();
728 #endif // EDIT_KEYFRAME
739 KeyFramePresetsList::KeyFramePresetsList(KeyFrameThread *thread,
740 KeyFrameWindow *window,
750 thread->presets_data)
752 this->thread = thread;
753 this->window = window;
756 int KeyFramePresetsList::selection_changed()
758 if(get_selection_number(0, 0) >= 0)
759 window->preset_text->update(
760 thread->presets_data->get(get_selection_number(0, 0))->get_text());
764 int KeyFramePresetsList::handle_event()
766 thread->apply_preset(window->preset_text->get_text());
780 KeyFramePresetsText::KeyFramePresetsText(KeyFrameThread *thread,
781 KeyFrameWindow *window,
791 this->thread = thread;
792 this->window = window;
795 int KeyFramePresetsText::handle_event()
816 KeyFramePresetsDelete::KeyFramePresetsDelete(KeyFrameThread *thread,
817 KeyFrameWindow *window,
820 : BC_GenericButton(x, y, _("Delete"))
822 this->thread = thread;
823 this->window = window;
826 int KeyFramePresetsDelete::handle_event()
828 thread->delete_preset(window->preset_text->get_text());
838 KeyFramePresetsSave::KeyFramePresetsSave(KeyFrameThread *thread,
839 KeyFrameWindow *window,
842 : BC_GenericButton(x, y, _("Save"))
844 this->thread = thread;
845 this->window = window;
848 int KeyFramePresetsSave::handle_event()
850 thread->save_preset(window->preset_text->get_text());
861 KeyFramePresetsApply::KeyFramePresetsApply(KeyFrameThread *thread,
862 KeyFrameWindow *window,
865 : BC_GenericButton(x, y, _("Apply"))
867 this->thread = thread;
868 this->window = window;
871 int KeyFramePresetsApply::handle_event()
873 thread->apply_preset(window->preset_text->get_text());
878 KeyFramePresetsOK::KeyFramePresetsOK(KeyFrameThread *thread,
879 KeyFrameWindow *window)
880 : BC_OKButton(window)
882 this->thread = thread;
883 this->window = window;
886 int KeyFramePresetsOK::keypress_event()
888 if(get_keypress() == RETURN)
891 if(thread->presets_db->preset_exists(thread->plugin_title,
892 window->preset_text->get_text()))
900 thread->save_preset(window->preset_text->get_text());