bsd lang segv fix, enable bsd lv2, lv2 gui enable fix, proxy/ffmpeg toggle resize...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / gwindowgui.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 "autoconf.h"
23 #include "bchash.h"
24 #include "bcsignals.h"
25 #include "clip.h"
26 #include "condition.h"
27 #include "edl.h"
28 #include "edlsession.h"
29 #include "gwindowgui.h"
30 #include "language.h"
31 #include "localsession.h"
32 #include "mainmenu.h"
33 #include "mainsession.h"
34 #include "mwindow.h"
35 #include "mwindowgui.h"
36 #include "theme.h"
37 #include "tracks.h"
38 #include "trackcanvas.h"
39 #include "zoombar.h"
40
41 #include <math.h>
42
43
44
45 GWindowGUI::GWindowGUI(MWindow *mwindow, int w, int h)
46  : BC_Window(_(PROGRAM_NAME ": Overlays"),
47         mwindow->session->gwindow_x, mwindow->session->gwindow_y,
48         w, h, w, h, 0, 0, 1)
49 {
50         this->mwindow = mwindow;
51         color_thread = 0;
52 }
53
54 GWindowGUI::~GWindowGUI()
55 {
56         delete color_thread;
57 }
58
59 void GWindowGUI::start_color_thread(GWindowColorButton *color_button)
60 {
61         unlock_window();
62         delete color_thread;
63         color_thread = new GWindowColorThread(color_button);
64         int color = auto_colors[color_button->auto_toggle->info->ref];
65         color_thread->start(color);
66         lock_window("GWindowGUI::start_color_thread");
67 }
68
69 const char *GWindowGUI::other_text[NON_AUTOMATION_TOTAL] =
70 {
71         N_("Assets"),
72         N_("Titles"),
73         N_("Transitions"),
74         N_("Plugin Keyframes")
75 };
76
77 const char *GWindowGUI::auto_text[AUTOMATION_TOTAL] =
78 {
79         N_("Mute"),
80         N_("Camera X"),
81         N_("Camera Y"),
82         N_("Camera Z"),
83         N_("Projector X"),
84         N_("Projector Y"),
85         N_("Projector Z"),
86         N_("Fade"),
87         N_("Pan"),
88         N_("Mode"),
89         N_("Mask"),
90         N_("Speed")
91 };
92
93 int GWindowGUI::auto_colors[AUTOMATION_TOTAL] =
94 {
95         PINK,
96         RED,
97         GREEN,
98         BLUE,
99         LTPINK,
100         LTGREEN,
101         LTBLUE,
102         LTPURPLE,
103         0,
104         0,
105         0,
106         ORANGE,
107 };
108
109 void GWindowGUI::load_defaults()
110 {
111         BC_Hash *defaults = mwindow->defaults;
112         auto_colors[AUTOMATION_MUTE] = defaults->get("AUTO_COLOR_MUTE", auto_colors[AUTOMATION_MUTE]);
113         auto_colors[AUTOMATION_CAMERA_X] = defaults->get("AUTO_COLOR_CAMERA_X", auto_colors[AUTOMATION_CAMERA_X]);
114         auto_colors[AUTOMATION_CAMERA_Y] = defaults->get("AUTO_COLOR_CAMERA_Y", auto_colors[AUTOMATION_CAMERA_Y]);
115         auto_colors[AUTOMATION_CAMERA_Z] = defaults->get("AUTO_COLOR_CAMERA_Z", auto_colors[AUTOMATION_CAMERA_Z]);
116         auto_colors[AUTOMATION_PROJECTOR_X] = defaults->get("AUTO_COLOR_PROJECTOR_X", auto_colors[AUTOMATION_PROJECTOR_X]);
117         auto_colors[AUTOMATION_PROJECTOR_Y] = defaults->get("AUTO_COLOR_PROJECTOR_Y", auto_colors[AUTOMATION_PROJECTOR_Y]);
118         auto_colors[AUTOMATION_PROJECTOR_Z] = defaults->get("AUTO_COLOR_PROJECTOR_Z", auto_colors[AUTOMATION_PROJECTOR_Z]);
119         auto_colors[AUTOMATION_FADE] = defaults->get("AUTO_COLOR_FADE", auto_colors[AUTOMATION_FADE]);
120         auto_colors[AUTOMATION_SPEED] = defaults->get("AUTO_COLOR_SPEED", auto_colors[AUTOMATION_SPEED]);
121 }
122
123 void GWindowGUI::save_defaults()
124 {
125         BC_Hash *defaults = mwindow->defaults;
126         defaults->update("AUTO_COLOR_MUTE", auto_colors[AUTOMATION_MUTE]);
127         defaults->update("AUTO_COLOR_CAMERA_X", auto_colors[AUTOMATION_CAMERA_X]);
128         defaults->update("AUTO_COLOR_CAMERA_Y", auto_colors[AUTOMATION_CAMERA_Y]);
129         defaults->update("AUTO_COLOR_CAMERA_Z", auto_colors[AUTOMATION_CAMERA_Z]);
130         defaults->update("AUTO_COLOR_PROJECTOR_X", auto_colors[AUTOMATION_PROJECTOR_X]);
131         defaults->update("AUTO_COLOR_PROJECTOR_Y", auto_colors[AUTOMATION_PROJECTOR_Y]);
132         defaults->update("AUTO_COLOR_PROJECTOR_Z", auto_colors[AUTOMATION_PROJECTOR_Z]);
133         defaults->update("AUTO_COLOR_FADE", auto_colors[AUTOMATION_FADE]);
134         defaults->update("AUTO_COLOR_SPEED", auto_colors[AUTOMATION_SPEED]);
135 }
136
137 static toggleinfo toggle_order[] =
138 {
139         {0, NON_AUTOMATION_ASSETS},
140         {0, NON_AUTOMATION_TITLES},
141         {0, NON_AUTOMATION_TRANSITIONS},
142         {0, NON_AUTOMATION_PLUGIN_AUTOS},
143         {0, -1}, // bar
144         {1, AUTOMATION_FADE},
145         {1, AUTOMATION_MUTE},
146         {1, AUTOMATION_SPEED},
147         {1, AUTOMATION_CAMERA_X},
148         {1, AUTOMATION_CAMERA_Y},
149         {1, AUTOMATION_CAMERA_Z},
150         {1, AUTOMATION_PROJECTOR_X},
151         {1, AUTOMATION_PROJECTOR_Y},
152         {1, AUTOMATION_PROJECTOR_Z},
153         {0, -1}, // bar
154         {1, AUTOMATION_MODE},
155         {1, AUTOMATION_PAN},
156         {1, AUTOMATION_MASK},
157 };
158
159 void GWindowGUI::calculate_extents(BC_WindowBase *gui, int *w, int *h)
160 {
161         int temp1, temp2, temp3, temp4, temp5, temp6, temp7;
162         int current_w, current_h;
163         *w = 10;
164         *h = 10;
165
166         for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
167                 toggleinfo *tp = &toggle_order[i];
168                 int isauto = tp->isauto, ref = tp->ref;
169                 if( ref < 0 ) {
170                         *h += get_resources()->bar_data->get_h() + 5;
171                         continue;
172                 }
173                 BC_Toggle::calculate_extents(gui,
174                         BC_WindowBase::get_resources()->checkbox_images,
175                         0, &temp1, &current_w, &current_h,
176                         &temp2, &temp3, &temp4, &temp5, &temp6, &temp7,
177                         _(isauto ?  auto_text[ref] : other_text[ref]),
178                         MEDIUMFONT);
179                 current_w += current_h;
180                 *w = MAX(current_w, *w);
181                 *h += current_h + 5;
182         }
183
184         *h += 10;
185         *w += 20;
186 }
187
188 GWindowColorButton::GWindowColorButton(GWindowToggle *auto_toggle, int x, int y, int w)
189  : BC_Button(x, y, w, vframes)
190 {
191         this->auto_toggle = auto_toggle;
192         this->color = 0;
193         for( int i=0; i<3; ++i ) {
194                 vframes[i] = new VFrame(w, w, BC_RGBA8888);
195                 vframes[i]->clear_frame();
196         }
197 }
198
199 GWindowColorButton::~GWindowColorButton()
200 {
201         for( int i=0; i<3; ++i )
202                 delete vframes[i];
203 }
204
205 void GWindowColorButton::set_color(int color)
206 {
207         this->color = color;
208         int r = (color>>16) & 0xff;
209         int g = (color>>8) & 0xff;
210         int b = (color>>0) & 0xff;
211         for( int i=0; i<3; ++i ) {
212                 VFrame *vframe = vframes[i];
213                 int ww = vframe->get_w(), hh = vframe->get_h();
214                 int cx = (ww+1)/2, cy = hh/2;
215                 double cc = (cx*cx + cy*cy) / 4.;
216                 uint8_t *bp = vframe->get_data(), *dp = bp;
217                 uint8_t *ep = dp + vframe->get_data_size();
218                 int rr = r, gg = g, bb = b;
219                 int bpl = vframe->get_bytes_per_line();
220                 switch( i ) {
221                 case BUTTON_UP:
222                         break;
223                 case BUTTON_UPHI:
224                         if( (rr+=48) > 0xff ) rr = 0xff;
225                         if( (gg+=48) > 0xff ) gg = 0xff;
226                         if( (bb+=48) > 0xff ) bb = 0xff;
227                         break;
228                 case BUTTON_DOWNHI:
229                         if( (rr-=48) < 0x00 ) rr = 0x00;
230                         if( (gg-=48) < 0x00 ) gg = 0x00;
231                         if( (bb-=48) < 0x00 ) bb = 0x00;
232                         break;
233                 }
234                 while( dp < ep ) {
235                         int yy = (dp-bp) / bpl, xx = ((dp-bp) % bpl) >> 2;
236                         int dy = cy - yy, dx = cx - xx;
237                         double s = dx*dx + dy*dy - cc;
238                         double ss = s < 0 ? 1 : s >= cc ? 0 : 1 - s/cc;
239                         int aa = ss * 0xff;
240                         *dp++ = rr; *dp++ = gg; *dp++ = bb; *dp++ = aa;
241                 }
242         }
243         set_images(vframes);
244 }
245
246 void GWindowColorButton::update_gui(int color)
247 {
248         set_color(color);
249         draw_face();
250 }
251
252 GWindowColorThread::GWindowColorThread(GWindowColorButton *color_button)
253  : ColorPicker(0, color_button->auto_toggle->caption)
254 {
255         this->color = 0;
256         this->color_button = color_button;
257         color_update = new GWindowColorUpdate(this);
258 }
259
260 GWindowColorThread::~GWindowColorThread()
261 {
262         delete color_update;
263 }
264
265 void GWindowColorThread::start(int color)
266 {
267         start_window(color, 0, 1);
268         color_update->start();
269 }
270
271 void GWindowColorThread::handle_done_event(int result)
272 {
273         color_update->stop();
274         GWindowGUI *gui = color_button->auto_toggle->gui;
275         int ref = color_button->auto_toggle->info->ref;
276         gui->lock_window("GWindowColorThread::handle_done_event");
277         if( !result ) {
278                 GWindowGUI::auto_colors[ref] = color;
279                 color_button->auto_toggle->update_gui(color);
280                 gui->save_defaults();
281         }
282         else {
283                 color = GWindowGUI::auto_colors[ref];
284                 color_button->update_gui(color);
285         }
286         gui->unlock_window();
287         MWindowGUI *mwindow_gui = color_button->auto_toggle->gui->mwindow->gui;
288         mwindow_gui->lock_window("GWindowColorUpdate::run");
289         mwindow_gui->draw_overlays(1);
290         mwindow_gui->unlock_window();
291 }
292
293 int GWindowColorThread::handle_new_color(int color, int alpha)
294 {
295         this->color = color;
296         color_update->update_lock->unlock();
297         return 1;
298 }
299
300 void GWindowColorThread::update_gui()
301 {
302         color_button->update_gui(color);
303 }
304
305 GWindowColorUpdate::GWindowColorUpdate(GWindowColorThread *color_thread)
306  : Thread(1, 0, 0)
307 {
308         this->color_thread = color_thread;
309         this->update_lock = new Condition(0,"GWindowColorUpdate::update_lock");
310         done = 1;
311 }
312
313 GWindowColorUpdate::~GWindowColorUpdate()
314 {
315         stop();
316         delete update_lock;
317 }
318
319 void GWindowColorUpdate::start()
320 {
321         if( done ) {
322                 done = 0;
323                 Thread::start();
324         }
325 }
326
327 void GWindowColorUpdate::stop()
328 {
329         if( !done ) {
330                 done = 1;
331                 update_lock->unlock();
332                 join();
333         }
334 }
335
336 void GWindowColorUpdate::run()
337 {
338         while( !done ) {
339                 update_lock->lock("GWindowColorUpdate::run");
340                 if( done ) break;
341                 color_thread->update_gui();
342         }
343 }
344
345
346 int GWindowColorButton::handle_event()
347 {
348         GWindowGUI *gui = auto_toggle->gui;
349         gui->start_color_thread(this);
350         return 1;
351 }
352
353 void GWindowGUI::create_objects()
354 {
355         int x = 10, y = 10;
356         lock_window("GWindowGUI::create_objects 1");
357
358         for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
359                 toggleinfo *tp = &toggle_order[i];
360                 int ref = tp->ref;
361                 if( ref < 0 ) {
362                         BC_Bar *bar = new BC_Bar(x,y,get_w()-x-10);
363                         add_tool(bar);
364                         toggles[i] = 0;
365                         y += bar->get_h() + 5;
366                         continue;
367                 }
368                 VFrame *vframe = 0;
369                 switch( ref ) {
370                 case AUTOMATION_MODE: vframe = mwindow->theme->modekeyframe_data;  break;
371                 case AUTOMATION_PAN:  vframe = mwindow->theme->pankeyframe_data;   break;
372                 case AUTOMATION_MASK: vframe = mwindow->theme->maskkeyframe_data;  break;
373                 }
374                 const char *label = _(tp->isauto ? auto_text[tp->ref] : other_text[tp->ref]);
375                 int color = !tp->isauto ? -1 : auto_colors[tp->ref];
376                 GWindowToggle *toggle = new GWindowToggle(mwindow, this, x, y, label, color, tp);
377                 add_tool(toggles[i] = toggle);
378                 if( vframe )
379                         draw_vframe(vframe, get_w()-vframe->get_w()-10, y);
380                 else if( tp->isauto ) {
381                         int wh = toggle->get_h() - 4;
382                         GWindowColorButton *color_button =
383                                 new GWindowColorButton(toggle, get_w()-wh-10, y+2, wh);
384                         add_tool(color_button);
385                         color_button->set_color(color);
386                         color_button->draw_face();
387                 }
388                 y += toggles[i]->get_h() + 5;
389         }
390         unlock_window();
391 }
392
393 void GWindowGUI::update_mwindow()
394 {
395         unlock_window();
396         mwindow->gui->mainmenu->update_toggles(1);
397         lock_window("GWindowGUI::update_mwindow");
398 }
399
400 void GWindowGUI::update_toggles(int use_lock)
401 {
402         if(use_lock) lock_window("GWindowGUI::update_toggles");
403
404         for( int i=0; i<(int)(sizeof(toggle_order)/sizeof(toggle_order[0])); ++i ) {
405                 if( toggles[i] ) toggles[i]->update();
406         }
407
408         if(use_lock) unlock_window();
409 }
410
411 int GWindowGUI::translation_event()
412 {
413         mwindow->session->gwindow_x = get_x();
414         mwindow->session->gwindow_y = get_y();
415         return 0;
416 }
417
418 int GWindowGUI::close_event()
419 {
420         delete color_thread;  color_thread = 0;
421         hide_window();
422         mwindow->session->show_gwindow = 0;
423         unlock_window();
424
425         mwindow->gui->lock_window("GWindowGUI::close_event");
426         mwindow->gui->mainmenu->show_gwindow->set_checked(0);
427         mwindow->gui->unlock_window();
428
429         lock_window("GWindowGUI::close_event");
430         mwindow->save_defaults();
431         return 1;
432 }
433
434 int GWindowGUI::keypress_event()
435 {
436         switch(get_keypress()) {
437         case 'w':
438         case 'W':
439         case '0':
440                 if( ctrl_down() ) {
441                         close_event();
442                         return 1;
443                 }
444                 break;
445         }
446         return 0;
447 }
448
449
450 GWindowToggle::GWindowToggle(MWindow *mwindow, GWindowGUI *gui, int x, int y,
451         const char *text, int color, toggleinfo *info)
452  : BC_CheckBox(x, y, *get_main_value(mwindow, info), text, MEDIUMFONT, color)
453 {
454         this->mwindow = mwindow;
455         this->gui = gui;
456         this->info = info;
457         this->color = color;
458         this->color_button = 0;
459 }
460
461 GWindowToggle::~GWindowToggle()
462 {
463         delete color_button;
464 }
465
466 int GWindowToggle::handle_event()
467 {
468         int value = get_value();
469         *get_main_value(mwindow, info) = value;
470         gui->update_mwindow();
471
472
473 // Update stuff in MWindow
474         unlock_window();
475         mwindow->gui->lock_window("GWindowToggle::handle_event");
476         if( info->isauto ) {
477                 int autogroup_type = -1;
478                 switch( info->ref ) {
479                 case AUTOMATION_FADE:
480                         autogroup_type = mwindow->edl->tracks->recordable_video_tracks() ?
481                                 AUTOGROUPTYPE_VIDEO_FADE : AUTOGROUPTYPE_AUDIO_FADE ;
482                         break;
483                 case AUTOMATION_SPEED:
484                         autogroup_type = AUTOGROUPTYPE_SPEED;
485                         break;
486                 case AUTOMATION_CAMERA_X:
487                 case AUTOMATION_PROJECTOR_X:
488                         autogroup_type = AUTOGROUPTYPE_X;
489                         break;
490                 case AUTOMATION_CAMERA_Y:
491                 case AUTOMATION_PROJECTOR_Y:
492                         autogroup_type = AUTOGROUPTYPE_Y;
493                         break;
494                 case AUTOMATION_CAMERA_Z:
495                 case AUTOMATION_PROJECTOR_Z:
496                         autogroup_type = AUTOGROUPTYPE_ZOOM;
497                         break;
498                 }
499                 if( value && autogroup_type >= 0 ) {
500                         mwindow->edl->local_session->zoombar_showautotype = autogroup_type;
501                         mwindow->gui->zoombar->update_autozoom();
502                 }
503                 mwindow->gui->draw_overlays(1);
504         }
505         else {
506                 switch( info->ref ) {
507                 case NON_AUTOMATION_ASSETS:
508                 case NON_AUTOMATION_TITLES:
509                         mwindow->gui->update(1, 1, 0, 0, 1, 0, 0);
510                         break;
511
512                 case NON_AUTOMATION_TRANSITIONS:
513                 case NON_AUTOMATION_PLUGIN_AUTOS:
514                         mwindow->gui->draw_overlays(1);
515                         break;
516                 }
517         }
518
519         mwindow->gui->unlock_window();
520         lock_window("GWindowToggle::handle_event");
521
522         return 1;
523 }
524
525 int* GWindowToggle::get_main_value(MWindow *mwindow, toggleinfo *info)
526 {
527         if( info->isauto )
528                 return &mwindow->edl->session->auto_conf->autos[info->ref];
529
530         switch( info->ref ) {
531         case NON_AUTOMATION_ASSETS: return &mwindow->edl->session->show_assets;
532         case NON_AUTOMATION_TITLES: return &mwindow->edl->session->show_titles;
533         case NON_AUTOMATION_TRANSITIONS: return &mwindow->edl->session->auto_conf->transitions;
534         case NON_AUTOMATION_PLUGIN_AUTOS: return &mwindow->edl->session->auto_conf->plugins;
535         }
536         return 0;
537 }
538
539 void GWindowToggle::update()
540 {
541         int *vp = get_main_value(mwindow, info);
542         if( !vp ) return;
543         set_value(*vp);
544 }
545
546 void GWindowToggle::update_gui(int color)
547 {
548         BC_Toggle::color = color;
549         draw_face(1,0);
550 }
551