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()
63 for(int i = 0; i < KEYFRAME_COLUMNS; i++)
64 keyframe_data[i].remove_all_objects();
65 delete [] keyframe_data;
66 presets_data->remove_all_objects();
72 void KeyFrameThread::update_values()
74 // Get the current selection before deleting the tables
76 for(int i = 0; i < keyframe_data[0].size(); i++)
78 if(keyframe_data[0].get(i)->get_selected())
85 for(int i = 0; i < KEYFRAME_COLUMNS; i++)
86 keyframe_data[i].remove_all_objects();
89 // Must lock main window to read keyframe
90 mwindow->gui->lock_window("KeyFrameThread::update_values");
91 if(!plugin || !mwindow->edl->tracks->plugin_exists(plugin))
93 mwindow->gui->unlock_window();
97 KeyFrame *keyframe = 0;
98 if(this->keyframe && plugin->keyframe_exists(this->keyframe))
100 // If user edited a specific keyframe, use it.
101 keyframe = this->keyframe;
106 // Use currently highlighted keyframe
107 keyframe = plugin->get_prev_keyframe(
108 plugin->track->to_units(
109 mwindow->edl->local_session->get_selectionstart(1), 0),
116 char *text = 0, *extra = 0;
117 keyframe->get_contents(&hash, &text, &extra);
119 for(int i = 0; i < hash.size(); i++)
121 keyframe_data[0].append(new BC_ListBoxItem(hash.get_key(i)));
122 keyframe_data[1].append(new BC_ListBoxItem(hash.get_value(i)));
124 keyframe_data[0].append(new BC_ListBoxItem((char*)_("TEXT")));
125 keyframe_data[1].append(new BC_ListBoxItem(text));
131 column_width[0] = mwindow->session->keyframedialog_column1;
132 column_width[1] = mwindow->session->keyframedialog_column2;
133 if(selection >= 0 && selection < keyframe_data[0].size())
135 for(int i = 0; i < KEYFRAME_COLUMNS; i++)
136 keyframe_data[i].get(selection)->set_selected(1);
138 mwindow->gui->unlock_window();
143 void KeyFrameThread::start_window(Plugin *plugin, KeyFrame *keyframe)
146 if(!BC_DialogThread::is_running())
148 if(!mwindow->edl->tracks->plugin_exists(plugin)) return;
149 this->keyframe = keyframe;
150 this->plugin = plugin;
151 plugin->calculate_title(plugin_title, 0);
152 sprintf(window_title, _(PROGRAM_NAME ": %s Keyframe"), plugin_title);
154 calculate_preset_list();
159 mwindow->gui->unlock_window();
160 BC_DialogThread::start();
161 mwindow->gui->lock_window("KeyFrameThread::start_window");
165 BC_DialogThread::start();
169 BC_Window* KeyFrameThread::new_gui()
171 mwindow->gui->lock_window("KeyFrameThread::new_gui");
173 int x = mwindow->gui->get_abs_cursor_x(0) -
174 mwindow->session->plugindialog_w / 2;
175 int y = mwindow->gui->get_abs_cursor_y(0) -
176 mwindow->session->plugindialog_h / 2;
178 KeyFrameWindow *window = new KeyFrameWindow(mwindow,
184 window->create_objects();
187 mwindow->gui->unlock_window();
192 void KeyFrameThread::handle_done_event(int result)
197 const char *title = ((KeyFrameWindow*)get_gui())->preset_text->get_text();
203 void KeyFrameThread::handle_close_event(int result)
209 void KeyFrameThread::close_window()
211 lock_window("KeyFrameThread::close_window");
214 get_gui()->lock_window("KeyFrameThread::close_window");
215 get_gui()->set_done(1);
216 get_gui()->unlock_window();
223 void KeyFrameThread::calculate_preset_list()
225 presets_data->remove_all_objects();
226 int total_presets = presets_db->get_total_presets(plugin_title);
227 for(int i = 0; i < total_presets; i++)
229 presets_data->append(new BC_ListBoxItem(presets_db->get_preset_title(
236 void KeyFrameThread::update_gui(int update_value_text)
239 if(BC_DialogThread::is_running())
241 mwindow->gui->lock_window("KeyFrameThread::update_gui");
243 mwindow->gui->unlock_window();
245 lock_window("KeyFrameThread::update_gui");
246 KeyFrameWindow *window = (KeyFrameWindow*)get_gui();
249 window->lock_window("KeyFrameThread::update_gui");
250 window->keyframe_list->update(keyframe_data,
251 (const char **)column_titles,
254 window->keyframe_list->get_xposition(),
255 window->keyframe_list->get_yposition(),
256 window->keyframe_list->get_highlighted_item());
257 if( update_value_text )
259 int selection_number = window->keyframe_list->get_selection_number(0, 0);
260 if( selection_number >= 0 && selection_number < keyframe_data[1].size())
262 char *edit_value = keyframe_data[1].get(selection_number)->get_text();
263 window->value_text->update(edit_value);
266 window->unlock_window();
273 void KeyFrameThread::save_preset(const char *title)
275 get_gui()->unlock_window();
276 mwindow->gui->lock_window("KeyFrameThread::save_preset");
278 // Test EDL for plugin existence
279 if(!mwindow->edl->tracks->plugin_exists(plugin))
281 mwindow->gui->unlock_window();
282 get_gui()->lock_window("KeyFrameThread::save_preset 2");
287 // Get current plugin keyframe
288 EDL *edl = mwindow->edl;
289 Track *track = plugin->track;
290 KeyFrame *keyframe = plugin->get_prev_keyframe(
291 track->to_units(edl->local_session->get_selectionstart(1), 0),
295 presets_db->save_preset(plugin_title, title, keyframe->get_data());
297 mwindow->gui->unlock_window();
298 get_gui()->lock_window("KeyFrameThread::save_preset 2");
302 calculate_preset_list();
303 ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data,
309 void KeyFrameThread::delete_preset(const char *title)
311 get_gui()->unlock_window();
312 mwindow->gui->lock_window("KeyFrameThread::save_preset");
314 // Test EDL for plugin existence
315 if(!mwindow->edl->tracks->plugin_exists(plugin))
317 mwindow->gui->unlock_window();
318 get_gui()->lock_window("KeyFrameThread::delete_preset 1");
322 presets_db->delete_preset(plugin_title, title);
324 mwindow->gui->unlock_window();
325 get_gui()->lock_window("KeyFrameThread::delete_preset 2");
329 calculate_preset_list();
330 ((KeyFrameWindow*)get_gui())->preset_list->update(presets_data,
337 void KeyFrameThread::apply_preset(const char *title)
339 if(presets_db->preset_exists(plugin_title, title))
341 get_gui()->unlock_window();
342 mwindow->gui->lock_window("KeyFrameThread::apply_preset");
344 // Test EDL for plugin existence
345 if(!mwindow->edl->tracks->plugin_exists(plugin))
347 mwindow->gui->unlock_window();
348 get_gui()->lock_window("KeyFrameThread::delete_preset 1");
352 mwindow->undo->update_undo_before();
355 #ifdef USE_KEYFRAME_SPANNING
357 presets_db->load_preset(plugin_title, title, &keyframe);
358 plugin->keyframes->update_parameter(&keyframe);
360 KeyFrame *keyframe = plugin->get_keyframe();
361 presets_db->load_preset(plugin_title, title, keyframe);
363 mwindow->save_backup();
364 mwindow->undo->update_undo_after(_("apply preset"), LOAD_AUTOMATION);
366 mwindow->update_plugin_guis(0);
367 mwindow->gui->draw_overlays(1);
368 mwindow->sync_parameters(CHANGE_PARAMS);
372 mwindow->gui->unlock_window();
373 get_gui()->lock_window("KeyFrameThread::apply_preset");
378 void KeyFrameThread::apply_value()
380 const char *text = 0;
382 KeyFrameWindow *window = (KeyFrameWindow*)get_gui();
383 int selection = window->keyframe_list->get_selection_number(0, 0);
384 //printf("KeyFrameThread::apply_value %d %d\n", __LINE__, selection);
385 if(selection < 0) return;
387 if(selection == keyframe_data[0].size() - 1)
388 text = window->value_text->get_text();
391 char *key = keyframe_data[0].get(selection)->get_text();
392 const char *value = window->value_text->get_text();
393 hash.update(key, value);
396 get_gui()->unlock_window();
397 mwindow->gui->lock_window("KeyFrameThread::apply_value");
398 if(plugin && mwindow->edl->tracks->plugin_exists(plugin))
400 mwindow->undo->update_undo_before();
401 if(mwindow->session->keyframedialog_all)
403 // Search for all keyframes in selection but don't create a new one.
404 Track *track = plugin->track;
405 int64_t start = track->to_units(mwindow->edl->local_session->get_selectionstart(0), 0);
406 int64_t end = track->to_units(mwindow->edl->local_session->get_selectionend(0), 0);
408 for(KeyFrame *current = (KeyFrame*)plugin->keyframes->last;
410 current = (KeyFrame*)PREVIOUS)
413 if(current && current->position < end)
415 current->update_parameter(&hash, text, 0);
416 // Stop at beginning of range
417 if(current->position <= start) break;
423 KeyFrame* keyframe = (KeyFrame*)plugin->keyframes->default_auto;
424 keyframe->update_parameter(&hash, text, 0);
429 // Create new keyframe if enabled
430 KeyFrame *keyframe = plugin->get_keyframe();
431 keyframe->update_parameter(&hash, text, 0);
436 printf("KeyFrameThread::apply_value %d: plugin doesn't exist\n", __LINE__);
439 mwindow->save_backup();
440 mwindow->undo->update_undo_after(_("edit keyframe"), LOAD_AUTOMATION);
442 mwindow->update_plugin_guis(0);
443 mwindow->gui->draw_overlays(1);
444 mwindow->sync_parameters(CHANGE_PARAMS);
448 mwindow->gui->unlock_window();
452 get_gui()->lock_window("KeyFrameThread::apply_value");
458 KeyFrameWindow::KeyFrameWindow(MWindow *mwindow,
459 KeyFrameThread *thread,
463 : BC_Window(title_string,
466 mwindow->session->keyframedialog_w,
467 mwindow->session->keyframedialog_h,
474 this->mwindow = mwindow;
475 this->thread = thread;
478 void KeyFrameWindow::create_objects()
480 Theme *theme = mwindow->theme;
482 theme->get_keyframedialog_sizes(this);
483 thread->column_width[0] = mwindow->session->keyframedialog_column1;
484 thread->column_width[1] = mwindow->session->keyframedialog_column2;
485 lock_window("KeyFrameWindow::create_objects");
490 add_subwindow(title1 = new BC_Title(theme->keyframe_list_x,
491 theme->keyframe_list_y -
492 BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) -
493 theme->widget_border,
494 _("Keyframe parameters:"),
496 add_subwindow(keyframe_list = new KeyFrameList(thread,
498 theme->keyframe_list_x,
499 theme->keyframe_list_y,
500 theme->keyframe_list_w,
501 theme->keyframe_list_h));
502 // add_subwindow(title2 = new BC_Title(theme->keyframe_text_x,
503 // theme->keyframe_text_y - BC_Title::calculate_h(this, "P") - theme->widget_border,
504 // _("Global Text:")));
505 // add_subwindow(keyframe_text = new KeyFrameText(thread,
507 // theme->keyframe_text_x,
508 // theme->keyframe_text_y,
509 // theme->keyframe_text_w));
510 add_subwindow(title3 = new BC_Title(theme->keyframe_value_x,
511 theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border,
513 add_subwindow(value_text = new KeyFrameValue(thread,
515 theme->keyframe_value_x,
516 theme->keyframe_value_y,
517 theme->keyframe_value_w));
518 add_subwindow(all_toggle = new KeyFrameAll(thread,
520 theme->keyframe_all_x,
521 theme->keyframe_all_y));
527 add_subwindow(title4 = new BC_Title(theme->presets_list_x,
528 theme->presets_list_y -
529 BC_Title::calculate_h(this, (char*)"Py", LARGEFONT) -
530 theme->widget_border,
533 add_subwindow(preset_list = new KeyFramePresetsList(thread,
535 theme->presets_list_x,
536 theme->presets_list_y,
537 theme->presets_list_w,
538 theme->presets_list_h));
539 add_subwindow(title5 = new BC_Title(theme->presets_text_x,
540 theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border,
541 _("Preset title:")));
542 add_subwindow(preset_text = new KeyFramePresetsText(thread,
544 theme->presets_text_x,
545 theme->presets_text_y,
546 theme->presets_text_w));
547 add_subwindow(delete_preset = new KeyFramePresetsDelete(thread,
549 theme->presets_delete_x,
550 theme->presets_delete_y));
551 add_subwindow(save_preset = new KeyFramePresetsSave(thread,
553 theme->presets_save_x,
554 theme->presets_save_y));
555 add_subwindow(apply_preset = new KeyFramePresetsApply(thread,
557 theme->presets_apply_x,
558 theme->presets_apply_y));
563 add_subwindow(new KeyFramePresetsOK(thread, this));
564 add_subwindow(new BC_CancelButton(this));
570 int KeyFrameWindow::resize_event(int w, int h)
572 Theme *theme = mwindow->theme;
573 mwindow->session->keyframedialog_w = w;
574 mwindow->session->keyframedialog_h = h;
575 theme->get_keyframedialog_sizes(this);
579 title1->reposition_window(theme->keyframe_list_x,
580 theme->keyframe_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
581 // title2->reposition_window(theme->keyframe_text_x,
582 // theme->keyframe_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
583 title3->reposition_window(theme->keyframe_value_x,
584 theme->keyframe_value_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
585 keyframe_list->reposition_window(theme->keyframe_list_x,
586 theme->keyframe_list_y,
587 theme->keyframe_list_w,
588 theme->keyframe_list_h);
589 // text->reposition_window(theme->keyframe_text_x,
590 // theme->keyframe_text_y,
591 // theme->keyframe_text_w);
592 value_text->reposition_window(theme->keyframe_value_x,
593 theme->keyframe_value_y,
594 theme->keyframe_value_w);
595 all_toggle->reposition_window(theme->keyframe_all_x,
596 theme->keyframe_all_y);
598 #endif // EDIT_KEYFRAME
603 title4->reposition_window(theme->presets_list_x,
604 theme->presets_list_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
605 title5->reposition_window(theme->presets_text_x,
606 theme->presets_text_y - BC_Title::calculate_h(this, (char*)"P") - theme->widget_border);
607 preset_list->reposition_window(theme->presets_list_x,
608 theme->presets_list_y,
609 theme->presets_list_w,
610 theme->presets_list_h);
611 preset_text->reposition_window(theme->presets_text_x,
612 theme->presets_text_y,
613 theme->presets_text_w);
614 delete_preset->reposition_window(theme->presets_delete_x,
615 theme->presets_delete_y);
616 save_preset->reposition_window(theme->presets_save_x,
617 theme->presets_save_y);
618 apply_preset->reposition_window(theme->presets_apply_x,
619 theme->presets_apply_y);
630 KeyFrameList::KeyFrameList(KeyFrameThread *thread,
631 KeyFrameWindow *window,
641 thread->keyframe_data,
642 (const char **)thread->column_titles,
643 thread->column_width,
646 this->thread = thread;
647 this->window = window;
650 int KeyFrameList::selection_changed()
652 window->value_text->update(
653 thread->keyframe_data[1].get(get_selection_number(0, 0))->get_text());
657 int KeyFrameList::handle_event()
663 int KeyFrameList::column_resize_event()
665 thread->mwindow->session->keyframedialog_column1 = get_column_width(0);
666 thread->mwindow->session->keyframedialog_column2 = get_column_width(1);
673 // KeyFrameText::KeyFrameText(KeyFrameThread *thread,
674 // KeyFrameWindow *window,
684 // this->thread = thread;
685 // this->window = window;
688 // int KeyFrameText::handle_event()
695 KeyFrameValue::KeyFrameValue(KeyFrameThread *thread,
696 KeyFrameWindow *window,
706 this->thread = thread;
707 this->window = window;
710 int KeyFrameValue::handle_event()
712 thread->update_values();
720 KeyFrameAll::KeyFrameAll(KeyFrameThread *thread,
721 KeyFrameWindow *window,
726 thread->mwindow->session->keyframedialog_all,
727 _("Apply to all selected keyframes"))
729 this->thread = thread;
730 this->window = window;
733 int KeyFrameAll::handle_event()
735 thread->mwindow->session->keyframedialog_all = get_value();
739 #endif // EDIT_KEYFRAME
750 KeyFramePresetsList::KeyFramePresetsList(KeyFrameThread *thread,
751 KeyFrameWindow *window,
761 thread->presets_data)
763 this->thread = thread;
764 this->window = window;
767 int KeyFramePresetsList::selection_changed()
769 if(get_selection_number(0, 0) >= 0)
770 window->preset_text->update(
771 thread->presets_data->get(get_selection_number(0, 0))->get_text());
775 int KeyFramePresetsList::handle_event()
777 thread->apply_preset(window->preset_text->get_text());
791 KeyFramePresetsText::KeyFramePresetsText(KeyFrameThread *thread,
792 KeyFrameWindow *window,
802 this->thread = thread;
803 this->window = window;
806 int KeyFramePresetsText::handle_event()
827 KeyFramePresetsDelete::KeyFramePresetsDelete(KeyFrameThread *thread,
828 KeyFrameWindow *window,
831 : BC_GenericButton(x, y, _("Delete"))
833 this->thread = thread;
834 this->window = window;
837 int KeyFramePresetsDelete::handle_event()
839 thread->delete_preset(window->preset_text->get_text());
849 KeyFramePresetsSave::KeyFramePresetsSave(KeyFrameThread *thread,
850 KeyFrameWindow *window,
853 : BC_GenericButton(x, y, _("Save"))
855 this->thread = thread;
856 this->window = window;
859 int KeyFramePresetsSave::handle_event()
861 thread->save_preset(window->preset_text->get_text());
872 KeyFramePresetsApply::KeyFramePresetsApply(KeyFrameThread *thread,
873 KeyFrameWindow *window,
876 : BC_GenericButton(x, y, _("Apply"))
878 this->thread = thread;
879 this->window = window;
882 int KeyFramePresetsApply::handle_event()
884 thread->apply_preset(window->preset_text->get_text());
889 KeyFramePresetsOK::KeyFramePresetsOK(KeyFrameThread *thread,
890 KeyFrameWindow *window)
891 : BC_OKButton(window)
893 this->thread = thread;
894 this->window = window;
897 int KeyFramePresetsOK::keypress_event()
899 if(get_keypress() == RETURN)
902 if(thread->presets_db->preset_exists(thread->plugin_title,
903 window->preset_text->get_text()))
911 thread->save_preset(window->preset_text->get_text());