r860: Merge 2.1:
[cinelerra_cv.git] / cinelerra / preferencesthread.C
bloba57328be4db955c87e63d237a97f7a6ea5ddb50b
1 #include "aboutprefs.h"
2 #include "asset.h"
3 #include "audiodevice.inc"
4 #include "bcsignals.h"
5 #include "cache.h"
6 #include "cplayback.h"
7 #include "cwindow.h"
8 #include "cwindowgui.h"
9 #include "bchash.h"
10 #include "edl.h"
11 #include "edlsession.h"
12 #include "filesystem.h"
13 #include "fonts.h"
14 #include "interfaceprefs.h"
15 #include "keys.h"
16 #include "language.h"
17 #include "levelwindow.h"
18 #include "levelwindowgui.h"
19 #include "mainerror.h"
20 #include "meterpanel.h"
21 #include "mutex.h"
22 #include "mwindow.h"
23 #include "mwindowgui.h"
24 #include "patchbay.h"
25 #include "performanceprefs.h"
26 #include "playbackengine.h"
27 #include "playbackprefs.h"
28 #include "preferences.h"
29 #include "recordprefs.h"
30 #include "theme.h"
31 #include "trackcanvas.h"
32 #include "transportque.h"
33 #include "vwindow.h"
34 #include "vwindowgui.h"
36 #include <string.h>
40 #define WIDTH 750
41 #define HEIGHT 730
44 PreferencesMenuitem::PreferencesMenuitem(MWindow *mwindow)
45  : BC_MenuItem(_("Preferences..."), "Shift+P", 'P')
47         this->mwindow = mwindow; 
49         set_shift(1);
50         thread = new PreferencesThread(mwindow);
53 PreferencesMenuitem::~PreferencesMenuitem()
55         delete thread;
59 int PreferencesMenuitem::handle_event() 
61         if(!thread->running())
62         {
63                 thread->start();
64         }
65         else
66         {
67 // window_lock has to be locked but window can't be locked until after
68 // it is known to exist, so we neglect window_lock for now
69                 if(thread->window)
70                 {
71                         thread->window_lock->lock("SetFormat::handle_event");
72                         thread->window->lock_window("PreferencesMenuitem::handle_event");
73                         thread->window->raise_window();
74                         thread->window->unlock_window();
75                         thread->window_lock->unlock();
76                 }
77         }
78         return 1;
84 PreferencesThread::PreferencesThread(MWindow *mwindow)
85  : Thread()
87         this->mwindow = mwindow;
88         window = 0;
89         thread_running = 0;
90         window_lock = new Mutex("PreferencesThread::window_lock");
93 PreferencesThread::~PreferencesThread()
95         delete window_lock;
98 void PreferencesThread::run()
100         int need_new_indexes;
102         preferences = new Preferences;
103         edl = new EDL;
104         edl->create_objects();
105         current_dialog = mwindow->defaults->get("DEFAULTPREF", 0);
106         preferences->copy_from(mwindow->preferences);
107         edl->copy_session(mwindow->edl);
108         redraw_indexes = 0;
109         redraw_meters = 0;
110         redraw_times = 0;
111         redraw_overlays = 0;
112         close_assets = 0;
113         reload_plugins = 0;
114         need_new_indexes = 0;
115         rerender = 0;
117         int x = mwindow->gui->get_root_w(0, 1) / 2 - WIDTH / 2;
118         int y = mwindow->gui->get_root_h(1) / 2 - HEIGHT / 2;
120         window_lock->lock("PreferencesThread::run 1");
121         window = new PreferencesWindow(mwindow, this, x, y);
122         window->create_objects();
123         window_lock->unlock();
125         thread_running = 1;
126         int result = window->run_window();
128         thread_running = 0;
129         if(!result)
130         {
131                 apply_settings();
132                 mwindow->save_defaults();
133         }
135         window_lock->lock("PreferencesThread::run 2");
136         delete window;
137         window = 0;
138         window_lock->unlock();
139         delete preferences;
140         delete edl;
142         mwindow->defaults->update("DEFAULTPREF", current_dialog);
145 int PreferencesThread::update_framerate()
147         if(thread_running && window)
148         {
149                 window->update_framerate();
150         }
151         return 0;
154 int PreferencesThread::apply_settings()
156 // Compare sessions                                                                                     
159         AudioOutConfig *this_aconfig = edl->session->playback_config->aconfig;
160         VideoOutConfig *this_vconfig = edl->session->playback_config->vconfig;
161         AudioOutConfig *aconfig = mwindow->edl->session->playback_config->aconfig;
162         VideoOutConfig *vconfig = mwindow->edl->session->playback_config->vconfig;
164         
165         rerender = 
166                 edl->session->need_rerender(mwindow->edl->session) ||
167                 (preferences->force_uniprocessor != preferences->force_uniprocessor) ||
168                 (*this_aconfig != *aconfig) ||
169                 (*this_vconfig != *vconfig) ||
170                 !preferences->brender_asset->equivalent(*mwindow->preferences->brender_asset, 0, 1);
175         mwindow->edl->copy_session(edl, 1);
176         mwindow->preferences->copy_from(preferences);
177         mwindow->init_brender();
179         if(((mwindow->edl->session->output_w % 4) || 
180                 (mwindow->edl->session->output_h % 4)) && 
181                 mwindow->edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
182         {
183                 MainError::show_error(
184                         _("This project's dimensions are not multiples of 4 so\n"
185                         "it can't be rendered by OpenGL."));
186         }
189         if(redraw_meters)
190         {
191                 mwindow->cwindow->gui->lock_window("PreferencesThread::apply_settings");
192                 mwindow->cwindow->gui->meters->change_format(edl->session->meter_format,
193                         edl->session->min_meter_db,
194                         edl->session->max_meter_db);
195                 mwindow->cwindow->gui->unlock_window();
199                 mwindow->vwindow->gui->lock_window("PreferencesThread::apply_settings");
200                 mwindow->vwindow->gui->meters->change_format(edl->session->meter_format,
201                         edl->session->min_meter_db,
202                         edl->session->max_meter_db);
203                 mwindow->vwindow->gui->unlock_window();
207                 mwindow->gui->lock_window("PreferencesThread::apply_settings 1");
208                 mwindow->gui->patchbay->change_meter_format(edl->session->meter_format,
209                         edl->session->min_meter_db,
210                         edl->session->max_meter_db);
211                 mwindow->gui->unlock_window();
215                 mwindow->lwindow->gui->lock_window("PreferencesThread::apply_settings");
216                 mwindow->lwindow->gui->panel->change_format(edl->session->meter_format,
217                         edl->session->min_meter_db,
218                         edl->session->max_meter_db);
219                 mwindow->lwindow->gui->unlock_window();
220         }
222         if(redraw_overlays)
223         {
224                 mwindow->gui->lock_window("PreferencesThread::apply_settings 2");
225                 mwindow->gui->canvas->draw_overlays();
226                 mwindow->gui->canvas->flash();
227                 mwindow->gui->unlock_window();
228         }
230         if(redraw_times)
231         {
232                 mwindow->gui->lock_window("PreferencesThread::apply_settings 3");
233                 mwindow->gui->update(0, 0, 1, 0, 0, 1, 0);
234                 mwindow->gui->redraw_time_dependancies();
235                 mwindow->gui->unlock_window();
236         }
238         if(rerender)
239         {
240 //printf("PreferencesThread::apply_settings 1\n");
241 // This doesn't stop and restart, only reloads the assets before
242 // the next play command.
243                 mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME,
244                         CHANGE_ALL,
245                         mwindow->edl,
246                         1);
247 //printf("PreferencesThread::apply_settings 10\n");
248         }
250         if(redraw_times || redraw_overlays)
251         {
252                 mwindow->gui->lock_window("PreferencesThread::apply_settings 4");
253                 mwindow->gui->flush();
254                 mwindow->gui->unlock_window();
255         }
256         return 0;
259 char* PreferencesThread::category_to_text(int category)
261         switch(category)
262         {
263                 case PLAYBACK:
264                         return _("Playback");
265                         break;
266                 case RECORD:
267                         return _("Recording");
268                         break;
269                 case PERFORMANCE:
270                         return _("Performance");
271                         break;
272                 case INTERFACE:
273                         return _("Interface");
274                         break;
275                 case ABOUT:
276                         return _("About");
277                         break;
278         }
279         return "";
282 int PreferencesThread::text_to_category(char *category)
284 SET_TRACE
285         int min_result = -1, result, result_num = 0;
286         for(int i = 0; i < CATEGORIES; i++)
287         {
288                 result = labs(strcmp(category_to_text(i), category));
289                 if(result < min_result || min_result < 0) 
290                 {
291                         min_result = result;
292                         result_num = i;
293                 }
294         }
295 SET_TRACE
296         return result_num;
306 PreferencesWindow::PreferencesWindow(MWindow *mwindow, 
307         PreferencesThread *thread,
308         int x,
309         int y)
310  : BC_Window(PROGRAM_NAME ": Preferences", 
311         x,
312         y,
313         WIDTH, 
314         HEIGHT,
315         (int)BC_INFINITY,
316         (int)BC_INFINITY,
317         0,
318         0,
319         1)
321         this->mwindow = mwindow;
322         this->thread = thread;
323         dialog = 0;
324         category = 0;
327 PreferencesWindow::~PreferencesWindow()
329         delete category;
330         if(dialog) delete dialog;
331         for(int i = 0; i < categories.total; i++)
332                 delete categories.values[i];
335 int PreferencesWindow::create_objects()
337         BC_Button *button;
341         mwindow->theme->draw_preferences_bg(this);
342         flash();
344         int x = mwindow->theme->preferencescategory_x;
345         int y = mwindow->theme->preferencescategory_y;
346         for(int i = 0; i < CATEGORIES; i++)
347         {
348                 add_subwindow(category_button[i] = new PreferencesButton(mwindow,
349                         thread,
350                         x,
351                         y,
352                         i,
353                         thread->category_to_text(i),
354                         (i == thread->current_dialog) ?
355                                 mwindow->theme->get_image_set("category_button_checked") : 
356                                 mwindow->theme->get_image_set("category_button")));
357                 x += category_button[i]->get_w() -
358                         mwindow->theme->preferences_category_overlap;
359         }
362 //      for(int i = 0; i < CATEGORIES; i++)
363 //              categories.append(new BC_ListBoxItem(thread->category_to_text(i)));
364 //      category = new PreferencesCategory(mwindow, 
365 //              thread, 
366 //              mwindow->theme->preferencescategory_x, 
367 //              mwindow->theme->preferencescategory_y);
368 //      category->create_objects();
371         add_subwindow(button = new PreferencesOK(mwindow, thread));
372         add_subwindow(new PreferencesApply(mwindow, thread));
373         add_subwindow(new PreferencesCancel(mwindow, thread));
375         set_current_dialog(thread->current_dialog);
376         show_window();
377         return 0;
380 int PreferencesWindow::update_framerate()
382         lock_window("PreferencesWindow::update_framerate");
383         if(thread->current_dialog == 0)
384         {
385                 thread->edl->session->actual_frame_rate = 
386                         mwindow->edl->session->actual_frame_rate;
387                 dialog->draw_framerate();
388                 flash();
389         }
390         unlock_window();
391         return 0;
394 int PreferencesWindow::set_current_dialog(int number)
396         thread->current_dialog = number;
397         if(dialog) delete dialog;
398         dialog = 0;
400 // Redraw category buttons
401         for(int i = 0; i < CATEGORIES; i++)
402         {
403                 if(i == number)
404                 {
405                         category_button[i]->set_images(
406                                 mwindow->theme->get_image_set("category_button_checked"));
407                 }
408                 else
409                 {
410                         category_button[i]->set_images(
411                                 mwindow->theme->get_image_set("category_button"));
412                 }
413                 category_button[i]->draw_face();
415 // Copy face to background for next button's overlap.
416 // Still can't to state changes right.
417         }
419         switch(number)
420         {
421                 case PreferencesThread::PLAYBACK:
422                         add_subwindow(dialog = new PlaybackPrefs(mwindow, this));
423                         break;
424         
425                 case PreferencesThread::RECORD:
426                         add_subwindow(dialog = new RecordPrefs(mwindow, this));
427                         break;
428         
429                 case PreferencesThread::PERFORMANCE:
430                         add_subwindow(dialog = new PerformancePrefs(mwindow, this));
431                         break;
432         
433                 case PreferencesThread::INTERFACE:
434                         add_subwindow(dialog = new InterfacePrefs(mwindow, this));
435                         break;
436         
437                 case PreferencesThread::ABOUT:
438                         add_subwindow(dialog = new AboutPrefs(mwindow, this));
439                         break;
440         }
442         if(dialog)
443         {
444                 dialog->draw_top_background(this, 0, 0, dialog->get_w(), dialog->get_h());
445                 dialog->flash();
446                 dialog->create_objects();
447         }
448         return 0;
461 PreferencesButton::PreferencesButton(MWindow *mwindow, 
462         PreferencesThread *thread, 
463         int x, 
464         int y,
465         int category,
466         char *text,
467         VFrame **images)
468  : BC_GenericButton(x, y, text, images)
470         this->mwindow = mwindow;
471         this->thread = thread;
472         this->category = category;
475 int PreferencesButton::handle_event()
477         thread->window->set_current_dialog(category);
478         return 1;
489 PreferencesDialog::PreferencesDialog(MWindow *mwindow, PreferencesWindow *pwindow)
490  : BC_SubWindow(10, 
491         40, 
492         pwindow->get_w() - 20, 
493         pwindow->get_h() - BC_GenericButton::calculate_h() - 10 - 40)
495         this->pwindow = pwindow;
496         this->mwindow = mwindow;
497         preferences = pwindow->thread->preferences;
500 PreferencesDialog::~PreferencesDialog()
504 // ============================== category window
509 PreferencesApply::PreferencesApply(MWindow *mwindow, PreferencesThread *thread)
510  : BC_GenericButton(thread->window->get_w() / 2 - BC_GenericButton::calculate_w(thread->window, _("Apply")) / 2, 
511         thread->window->get_h() - BC_GenericButton::calculate_h() - 10, 
512         _("Apply"))
514         this->mwindow = mwindow;
515         this->thread = thread;
518 int PreferencesApply::handle_event()
520         thread->apply_settings();
521         return 1;
527 PreferencesOK::PreferencesOK(MWindow *mwindow, PreferencesThread *thread)
528  : BC_GenericButton(10, 
529         thread->window->get_h() - BC_GenericButton::calculate_h() - 10,
530         _("OK"))
532         this->mwindow = mwindow;
533         this->thread = thread;
536 int PreferencesOK::keypress_event()
538         if(get_keypress() == RETURN)
539         {
540                 thread->window->set_done(0);
541                 return 1;
542         }
543         return 0;
545 int PreferencesOK::handle_event()
547         thread->window->set_done(0);
548         return 1;
553 PreferencesCancel::PreferencesCancel(MWindow *mwindow, PreferencesThread *thread)
554  : BC_GenericButton(thread->window->get_w() - BC_GenericButton::calculate_w(thread->window, _("Cancel")) - 10,
555         thread->window->get_h() - BC_GenericButton::calculate_h() - 10,
556         _("Cancel"))
558         this->mwindow = mwindow;
559         this->thread = thread;
561 int PreferencesCancel::keypress_event()
563         if(get_keypress() == ESC)
564         {
565                 thread->window->set_done(1);
566                 return 1;
567         }
568         return 0;
571 int PreferencesCancel::handle_event()
573         thread->window->set_done(1);
574         return 1;
586 PreferencesCategory::PreferencesCategory(MWindow *mwindow, PreferencesThread *thread, int x, int y)
587  : BC_PopupTextBox(thread->window, 
588                 &thread->window->categories,
589                 thread->category_to_text(thread->current_dialog),
590                 x, 
591                 y, 
592                 200,
593                 150)
595         this->mwindow = mwindow;
596         this->thread = thread;
599 PreferencesCategory::~PreferencesCategory()
603 int PreferencesCategory::handle_event()
605 SET_TRACE
606         thread->window->set_current_dialog(thread->text_to_category(get_text()));
607 SET_TRACE
608         return 1;