popup menu mods/pref, pactl fix
[goodguy/history.git] / cinelerra-5.1 / cinelerra / keyframepopup.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
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.
10  * 
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.
15  * 
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
19  * 
20  */
21
22 #include "apatchgui.h"
23 #include "autoconf.h"
24 #include "autos.h"
25 #include "bcwindowbase.h"
26 #include "cpanel.h"
27 #include "cwindowgui.h" 
28 #include "cwindow.h"
29 #include "edl.h"
30 #include "edlsession.h"
31 #include "filexml.h"
32 #include "gwindow.h"
33 #include "gwindowgui.h"
34 #include "keyframe.h"
35 #include "keyframepopup.h"
36 #include "language.h"
37 #include "localsession.h"
38 #include "maincursor.h"
39 #include "mainmenu.h"
40 #include "mainundo.h"
41 #include "mwindowgui.h"
42 #include "mwindow.h"
43 #include "patchbay.h"
44 #include "patchgui.h" 
45 #include "track.h"
46 #include "vpatchgui.h"
47
48 KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
49  : BC_PopupMenu(0, 0, 0, "", 0)
50 {
51         this->mwindow = mwindow;
52         this->gui = gui;
53         key_hide = 0;
54         key_show = 0;
55         key_delete = 0;
56         key_copy = 0;
57         key_smooth = 0;
58         key_linear = 0;
59         key_free = 0;
60         key_mbar = 0;
61         key_mode_displayed = false;
62         key_edit_displayed = false;
63 }
64
65 KeyframePopup::~KeyframePopup()
66 {
67         if( !key_mode_displayed ) {
68                 delete key_mbar;
69                 delete key_smooth;
70                 delete key_linear;
71                 delete key_free_t;
72                 delete key_free;
73         }
74         if( !key_edit_displayed ) {
75                 delete key_edit;
76         }
77 }
78
79 void KeyframePopup::create_objects()
80 {
81         add_item(key_hide = new KeyframePopupHide(mwindow, this));
82         add_item(key_show = new KeyframePopupShow(mwindow, this));
83         add_item(key_delete = new KeyframePopupDelete(mwindow, this));
84         add_item(key_copy = new KeyframePopupCopy(mwindow, this));
85
86         key_edit   = new KeyframePopupEdit(mwindow, this);
87         key_mbar   = new BC_MenuItem("-");
88         key_smooth = new KeyframePopupCurveMode(mwindow, this, FloatAuto::SMOOTH);
89         key_linear = new KeyframePopupCurveMode(mwindow, this, FloatAuto::LINEAR);
90         key_free_t = new KeyframePopupCurveMode(mwindow, this, FloatAuto::TFREE );
91         key_free   = new KeyframePopupCurveMode(mwindow, this, FloatAuto::FREE  );
92 }
93
94 int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
95 {
96         this->keyframe_plugin = plugin;
97         this->keyframe_auto = keyframe;
98         this->keyframe_autos = 0;
99         this->keyframe_automation = 0;
100         handle_curve_mode(0, 0);
101         return 0;
102 }
103
104 int KeyframePopup::update(Automation *automation, Autos *autos, Auto *auto_keyframe)
105 {
106         this->keyframe_plugin = 0;
107         this->keyframe_automation = automation;
108         this->keyframe_autos = autos;
109         this->keyframe_auto = auto_keyframe;
110         handle_curve_mode(autos, auto_keyframe);
111
112         /* snap to cursor */
113         double current_position = mwindow->edl->local_session->get_selectionstart(1);
114         double new_position = keyframe_automation->track->from_units(keyframe_auto->position);
115         mwindow->edl->local_session->set_selectionstart(new_position);
116         mwindow->edl->local_session->set_selectionend(new_position);
117         if (current_position != new_position)
118         {
119                 mwindow->edl->local_session->set_selectionstart(new_position);
120                 mwindow->edl->local_session->set_selectionend(new_position);
121                 mwindow->gui->lock_window();
122                 mwindow->gui->update(1, 1, 1, 1, 1, 1, 0);      
123                 mwindow->gui->unlock_window();
124         }
125         return 0;
126 }
127
128 void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
129 // determines the type of automation node. if floatauto, adds
130 // menu entries showing the curve mode of the node
131 {
132         deactivate();
133         if( !key_edit_displayed && keyframe_plugin ) {
134                 add_item(key_edit);
135                 key_edit_displayed = true;
136         }
137         else if( key_edit_displayed && !keyframe_plugin ) {
138                 remove_item(key_edit);
139                 key_edit_displayed = false;
140         }
141
142         if(!key_mode_displayed && autos && autos->get_type() == AUTOMATION_TYPE_FLOAT)
143         { // append additional menu entries showing the curve_mode
144                 add_item(key_mbar);
145                 add_item(key_smooth);
146                 add_item(key_linear);
147                 add_item(key_free_t);
148                 add_item(key_free);
149                 key_mode_displayed = true;
150         }
151         else if(key_mode_displayed && (!autos || autos->get_type() != AUTOMATION_TYPE_FLOAT))
152         { // remove additional menu entries
153                 remove_item(key_free);
154                 remove_item(key_free_t);
155                 remove_item(key_linear);
156                 remove_item(key_smooth);
157                 remove_item(key_mbar);
158                 key_mode_displayed = false;
159         }
160         if(key_mode_displayed && auto_keyframe)
161         { // set checkmarks to display current mode
162                 key_smooth->toggle_mode((FloatAuto*)auto_keyframe);
163                 key_linear->toggle_mode((FloatAuto*)auto_keyframe);
164                 key_free_t->toggle_mode((FloatAuto*)auto_keyframe);
165                 key_free  ->toggle_mode((FloatAuto*)auto_keyframe);
166         }
167         activate();
168 }
169
170 KeyframePopupDelete::KeyframePopupDelete(MWindow *mwindow, KeyframePopup *popup)
171  : BC_MenuItem(_("Delete keyframe"))
172 {
173         this->mwindow = mwindow;
174         this->popup = popup;
175 }
176
177 KeyframePopupDelete::~KeyframePopupDelete()
178 {
179 }
180
181 int KeyframePopupDelete::handle_event()
182 {
183         mwindow->undo->update_undo_before(_("delete keyframe"), 0);
184         delete popup->keyframe_auto;
185         mwindow->undo->update_undo_after(_("delete keyframe"), LOAD_ALL);
186
187         mwindow->save_backup();
188         mwindow->gui->update(0, 1,      // 1 for incremental drawing.  2 for full refresh
189                 0, 0, 0, 0, 0);
190         mwindow->update_plugin_guis();
191         mwindow->restart_brender();
192         mwindow->sync_parameters(CHANGE_EDL);
193
194         return 1;
195 }
196
197 KeyframePopupHide::KeyframePopupHide(MWindow *mwindow, KeyframePopup *popup)
198  : BC_MenuItem(_("Hide keyframe type"))
199 {
200         this->mwindow = mwindow;
201         this->popup = popup;
202 }
203
204 KeyframePopupHide::~KeyframePopupHide()
205 {
206 }
207
208 int KeyframePopupHide::handle_event()
209 {
210         if( popup->keyframe_autos )
211                 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
212         return 1;
213 }
214
215 KeyframePopupShow::KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup)
216  : BC_MenuItem(_("Show keyframe settings"))
217 {
218         this->mwindow = mwindow;
219         this->popup = popup;
220 }
221
222 KeyframePopupShow::~KeyframePopupShow()
223 {
224 }
225
226 int KeyframePopupShow::handle_event()
227 {
228         if (popup->keyframe_plugin)
229         {
230                 mwindow->update_plugin_guis();
231                 mwindow->show_plugin(popup->keyframe_plugin);
232         }
233         else if( popup->keyframe_automation ) {
234 /*
235
236                 mwindow->cwindow->gui->lock_window();
237                 int show_window = 1;
238                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos ||
239                    popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
240                    
241                 {
242                         mwindow->cwindow->gui->set_operation(CWINDOW_PROJECTOR);        
243                 } else
244                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos ||
245                    popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
246                    
247                 {
248                         mwindow->cwindow->gui->set_operation(CWINDOW_CAMERA);   
249                 } else
250                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
251                    
252                 {
253                         // no window to be shown
254                         show_window = 0;
255                         // first find the appropriate patchgui
256                         PatchBay *patchbay = mwindow->gui->patchbay;
257                         PatchGUI *patchgui = 0;
258                         for (int i = 0; i < patchbay->patches.total; i++)
259                                 if (patchbay->patches.values[i]->track == popup->keyframe_automation->track)
260                                         patchgui = patchbay->patches.values[i];         
261                         if (patchgui != 0)
262                         {
263 // FIXME: repositioning of the listbox needs support in guicast
264 //                              int cursor_x = popup->get_relative_cursor_x();
265 //                              int cursor_y = popup->get_relative_cursor_y();
266 //                              vpatchgui->mode->reposition_window(cursor_x, cursor_y);
267
268
269 // Open the popup menu
270                                 VPatchGUI *vpatchgui = (VPatchGUI *)patchgui;
271                                 vpatchgui->mode->activate_menu();
272                         }
273                 } else
274                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
275                    
276                 {
277                         mwindow->cwindow->gui->set_operation(CWINDOW_MASK);     
278                 } else
279                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
280                    
281                 {
282                         // no window to be shown
283                         show_window = 0;
284                         // first find the appropriate patchgui
285                         PatchBay *patchbay = mwindow->gui->patchbay;
286                         PatchGUI *patchgui = 0;
287                         for (int i = 0; i < patchbay->patches.total; i++)
288                                 if (patchbay->patches.values[i]->track == popup->keyframe_automation->track)
289                                         patchgui = patchbay->patches.values[i];         
290                         if (patchgui != 0)
291                         {
292 // Open the popup menu at current mouse position
293                                 APatchGUI *apatchgui = (APatchGUI *)patchgui;
294                                 int cursor_x = popup->get_relative_cursor_x();
295                                 int cursor_y = popup->get_relative_cursor_y();
296                                 apatchgui->pan->activate(cursor_x, cursor_y);
297                         }
298                         
299
300                 } else
301                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
302                    
303                 {
304                         // no window to be shown, so do nothing
305                         // IDEA: open window for fading
306                         show_window = 0;
307                 } else
308                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
309                    
310                 {
311                         // no window to be shown, so do nothing
312                         // IDEA: directly switch
313                         show_window = 0;
314                 } else;
315                 
316
317 // ensure bringing to front
318                 if (show_window)
319                 {
320                         ((CPanelToolWindow *)(mwindow->cwindow->gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]))->set_shown(0);
321                         ((CPanelToolWindow *)(mwindow->cwindow->gui->composite_panel->operation[CWINDOW_TOOL_WINDOW]))->set_shown(1);
322                 }
323                 mwindow->cwindow->gui->unlock_window();
324
325
326 */
327         }
328         return 1;
329 }
330
331
332
333 KeyframePopupCopy::KeyframePopupCopy(MWindow *mwindow, KeyframePopup *popup)
334  : BC_MenuItem(_("Copy keyframe"))
335 {
336         this->mwindow = mwindow;
337         this->popup = popup;
338 }
339
340 KeyframePopupCopy::~KeyframePopupCopy()
341 {
342 }
343
344 int KeyframePopupCopy::handle_event()
345 {
346 /*
347         FIXME:
348         we want to copy just keyframe under cursor, NOT all keyframes at this frame
349         - very hard to do, so this is good approximation for now...
350 */
351         
352 #if 0
353         if (popup->keyframe_automation)
354         {
355                 FileXML file;
356                 EDL *edl = mwindow->edl;
357                 Track *track = popup->keyframe_automation->track;
358                 int64_t position = popup->keyframe_auto->position;
359                 AutoConf autoconf;
360 // first find out type of our auto
361                 autoconf.set_all(0);
362                 if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->projector_autos)
363                         autoconf.projector = 1;
364                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pzoom_autos)
365                         autoconf.pzoom = 1;
366                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->camera_autos)
367                         autoconf.camera = 1;
368                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->czoom_autos)
369                         autoconf.czoom = 1;             
370                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mode_autos)
371                         autoconf.mode = 1;
372                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mask_autos)
373                         autoconf.mask = 1;
374                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->pan_autos)
375                         autoconf.pan = 1;                  
376                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->fade_autos)
377                         autoconf.fade = 1;
378                 else if (popup->keyframe_autos == (Autos *)popup->keyframe_automation->mute_autos)
379                         autoconf.mute = 1;              
380
381
382 // now create a clipboard
383                 file.tag.set_title("AUTO_CLIPBOARD");
384                 file.tag.set_property("LENGTH", 0);
385                 file.tag.set_property("FRAMERATE", edl->session->frame_rate);
386                 file.tag.set_property("SAMPLERATE", edl->session->sample_rate);
387                 file.append_tag();
388                 file.append_newline();
389                 file.append_newline();
390
391 /*              track->copy_automation(position, 
392                         position, 
393                         &file,
394                         0,
395                         0);
396                         */
397                 file.tag.set_title("TRACK");
398 // Video or audio
399                 track->save_header(&file);
400                 file.append_tag();
401                 file.append_newline();
402
403                 track->automation->copy(position, 
404                         position, 
405                         &file,
406                         0,
407                         0,
408                         &autoconf);
409                 
410                 
411                 
412                 file.tag.set_title("/TRACK");
413                 file.append_tag();
414                 file.append_newline();
415                 file.append_newline();
416                 file.append_newline();
417                 file.append_newline();
418
419
420
421                 file.tag.set_title("/AUTO_CLIPBOARD");
422                 file.append_tag();
423                 file.append_newline();
424                 file.terminate_string();
425
426                 mwindow->gui->lock_window();
427                 mwindow->gui->get_clipboard()->to_clipboard(file.string, 
428                         strlen(file.string), 
429                         SECONDARY_SELECTION);
430                 mwindow->gui->unlock_window();
431
432         } else
433 #endif
434                 mwindow->copy_automation();
435         return 1;
436 }
437
438
439
440 KeyframePopupCurveMode::KeyframePopupCurveMode(
441         MWindow *mwindow, 
442         KeyframePopup *popup, 
443         int curve_mode)
444  : BC_MenuItem( get_labeltext(curve_mode))
445 {
446         this->curve_mode = curve_mode;
447         this->mwindow = mwindow;
448         this->popup = popup;
449 }
450
451 KeyframePopupCurveMode::~KeyframePopupCurveMode() { }
452
453
454 const char* KeyframePopupCurveMode::get_labeltext(int mode)
455 {
456         switch(mode) {
457         case FloatAuto::SMOOTH: return _("smooth curve");
458         case FloatAuto::LINEAR: return _("linear segments");
459         case FloatAuto::TFREE:  return _("tangent edit");
460         case FloatAuto::FREE:   return _("disjoint edit");
461         }
462         return _("misconfigured");
463 }
464
465
466 void KeyframePopupCurveMode::toggle_mode(FloatAuto *keyframe)
467 {
468         set_checked(curve_mode == keyframe->curve_mode);
469 }
470
471
472 int KeyframePopupCurveMode::handle_event()
473 {
474         if (popup->keyframe_autos && 
475             popup->keyframe_autos->get_type() == AUTOMATION_TYPE_FLOAT)
476         {
477                 mwindow->undo->update_undo_before(_("change keyframe curve mode"), 0);
478                 ((FloatAuto*)popup->keyframe_auto)->
479                         change_curve_mode((FloatAuto::t_mode)curve_mode);
480                 
481                 // if we switched to some "auto" mode, this may imply a
482                 // real change to parameters, so this needs to be undoable...
483                 mwindow->undo->update_undo_after(_("change keyframe curve mode"), LOAD_ALL);
484                 mwindow->save_backup();
485                 
486                 mwindow->gui->update(0, 1, 0,0,0,0,0); // incremental redraw for canvas
487                 mwindow->cwindow->update(0,0, 1, 0,0); // redraw tool window in compositor
488                 mwindow->update_plugin_guis();
489                 mwindow->restart_brender();
490                 mwindow->sync_parameters(CHANGE_EDL);
491         }
492         return 1;
493 }
494
495
496 KeyframePopupEdit::KeyframePopupEdit(MWindow *mwindow, KeyframePopup *popup)
497  : BC_MenuItem(_("Edit Params..."))
498 {
499         this->mwindow = mwindow;
500         this->popup = popup;
501 }
502
503 int KeyframePopupEdit::handle_event()
504 {
505         mwindow->show_keyframe_gui(popup->keyframe_plugin);
506         return 1;
507 }
508
509
510 KeyframeHidePopup::KeyframeHidePopup(MWindow *mwindow, MWindowGUI *gui)
511  : BC_PopupMenu(0, 0, 0, "", 0)
512 {
513         this->mwindow = mwindow;
514         this->gui = gui;
515         this->keyframe_autos = 0;
516 }
517
518 KeyframeHidePopup::~KeyframeHidePopup()
519 {
520 }
521
522 void KeyframeHidePopup::create_objects()
523 {
524         add_item(new KeyframeHideItem(mwindow, this));
525 }
526
527 int KeyframeHidePopup::update(Autos *autos)
528 {
529         this->keyframe_autos = autos;
530         return 0;
531 }
532
533 KeyframeHideItem::KeyframeHideItem(MWindow *mwindow, KeyframeHidePopup *popup)
534  : BC_MenuItem(_("Hide keyframe type"))
535 {
536         this->mwindow = mwindow;
537         this->popup = popup;
538 }
539
540
541 int KeyframeHideItem::handle_event()
542 {
543         if( popup->keyframe_autos )
544                 mwindow->set_auto_visibility(popup->keyframe_autos, 0);
545         return 1;
546 }
547