r854: Merge 2.1:
[cinelerra_cv/ct.git] / cinelerra / preferencesthread.C
blobb6d6765b56b09717383c451a2a1599abce2c6c1a
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->playback_preload != mwindow->edl->session->playback_preload) ||
167                 (edl->session->interpolation_type != mwindow->edl->session->interpolation_type) ||
168                 (edl->session->video_every_frame != mwindow->edl->session->video_every_frame) ||
169                 (edl->session->real_time_playback != mwindow->edl->session->real_time_playback) ||
170                 (edl->session->playback_software_position != mwindow->edl->session->playback_software_position) ||
171                 (edl->session->test_playback_edits != mwindow->edl->session->test_playback_edits) ||
172                 (edl->session->playback_buffer != mwindow->edl->session->playback_buffer) ||
173                 (preferences->force_uniprocessor != preferences->force_uniprocessor) ||
174                 (*this_aconfig != *aconfig) ||
175                 (*this_vconfig != *vconfig) ||
176                 !preferences->brender_asset->equivalent(*mwindow->preferences->brender_asset, 0, 1);
181 // TODO: Need to copy just the parameters in PreferencesThread
182         mwindow->edl->copy_session(edl);
183         mwindow->preferences->copy_from(preferences);
184         mwindow->init_brender();
186         if(((mwindow->edl->session->output_w % 4) || 
187                 (mwindow->edl->session->output_h % 4)) && 
188                 mwindow->edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL)
189         {
190                 MainError::show_error(
191                         _("This project's dimensions are not multiples of 4 so\n"
192                         "it can't be rendered by OpenGL."));
193         }
196         if(redraw_meters)
197         {
198                 mwindow->cwindow->gui->lock_window("PreferencesThread::apply_settings");
199                 mwindow->cwindow->gui->meters->change_format(edl->session->meter_format,
200                         edl->session->min_meter_db,
201                         edl->session->max_meter_db);
202                 mwindow->cwindow->gui->unlock_window();
206                 mwindow->vwindow->gui->lock_window("PreferencesThread::apply_settings");
207                 mwindow->vwindow->gui->meters->change_format(edl->session->meter_format,
208                         edl->session->min_meter_db,
209                         edl->session->max_meter_db);
210                 mwindow->vwindow->gui->unlock_window();
214                 mwindow->gui->lock_window("PreferencesThread::apply_settings 1");
215                 mwindow->gui->patchbay->change_meter_format(edl->session->meter_format,
216                         edl->session->min_meter_db,
217                         edl->session->max_meter_db);
218                 mwindow->gui->unlock_window();
222                 mwindow->lwindow->gui->lock_window("PreferencesThread::apply_settings");
223                 mwindow->lwindow->gui->panel->change_format(edl->session->meter_format,
224                         edl->session->min_meter_db,
225                         edl->session->max_meter_db);
226                 mwindow->lwindow->gui->unlock_window();
227         }
229         if(redraw_overlays)
230         {
231                 mwindow->gui->lock_window("PreferencesThread::apply_settings 2");
232                 mwindow->gui->canvas->draw_overlays();
233                 mwindow->gui->canvas->flash();
234                 mwindow->gui->unlock_window();
235         }
237         if(redraw_times)
238         {
239                 mwindow->gui->lock_window("PreferencesThread::apply_settings 3");
240                 mwindow->gui->update(0, 0, 1, 0, 0, 1, 0);
241                 mwindow->gui->redraw_time_dependancies();
242                 mwindow->gui->unlock_window();
243         }
245         if(rerender)
246         {
247 //printf("PreferencesThread::apply_settings 1\n");
248 // This doesn't stop and restart, only reloads the assets before
249 // the next play command.
250                 mwindow->cwindow->playback_engine->que->send_command(CURRENT_FRAME,
251                         CHANGE_ALL,
252                         mwindow->edl,
253                         1);
254 //printf("PreferencesThread::apply_settings 10\n");
255         }
257         if(redraw_times || redraw_overlays)
258         {
259                 mwindow->gui->lock_window("PreferencesThread::apply_settings 4");
260                 mwindow->gui->flush();
261                 mwindow->gui->unlock_window();
262         }
263         return 0;
266 char* PreferencesThread::category_to_text(int category)
268         switch(category)
269         {
270                 case PLAYBACK:
271                         return _("Playback");
272                         break;
273                 case RECORD:
274                         return _("Recording");
275                         break;
276                 case PERFORMANCE:
277                         return _("Performance");
278                         break;
279                 case INTERFACE:
280                         return _("Interface");
281                         break;
282                 case ABOUT:
283                         return _("About");
284                         break;
285         }
286         return "";
289 int PreferencesThread::text_to_category(char *category)
291 SET_TRACE
292         int min_result = -1, result, result_num = 0;
293         for(int i = 0; i < CATEGORIES; i++)
294         {
295                 result = labs(strcmp(category_to_text(i), category));
296                 if(result < min_result || min_result < 0) 
297                 {
298                         min_result = result;
299                         result_num = i;
300                 }
301         }
302 SET_TRACE
303         return result_num;
313 PreferencesWindow::PreferencesWindow(MWindow *mwindow, 
314         PreferencesThread *thread,
315         int x,
316         int y)
317  : BC_Window(PROGRAM_NAME ": Preferences", 
318         x,
319         y,
320         WIDTH, 
321         HEIGHT,
322         (int)BC_INFINITY,
323         (int)BC_INFINITY,
324         0,
325         0,
326         1)
328         this->mwindow = mwindow;
329         this->thread = thread;
330         dialog = 0;
331         category = 0;
334 PreferencesWindow::~PreferencesWindow()
336         delete category;
337         if(dialog) delete dialog;
338         for(int i = 0; i < categories.total; i++)
339                 delete categories.values[i];
342 int PreferencesWindow::create_objects()
344         BC_Button *button;
348         mwindow->theme->draw_preferences_bg(this);
349         flash();
351         int x = mwindow->theme->preferencescategory_x;
352         int y = mwindow->theme->preferencescategory_y;
353         for(int i = 0; i < CATEGORIES; i++)
354         {
355                 add_subwindow(category_button[i] = new PreferencesButton(mwindow,
356                         thread,
357                         x,
358                         y,
359                         i,
360                         thread->category_to_text(i),
361                         (i == thread->current_dialog) ?
362                                 mwindow->theme->get_image_set("category_button_checked") : 
363                                 mwindow->theme->get_image_set("category_button")));
364                 x += category_button[i]->get_w() -
365                         mwindow->theme->preferences_category_overlap;
366         }
369 //      for(int i = 0; i < CATEGORIES; i++)
370 //              categories.append(new BC_ListBoxItem(thread->category_to_text(i)));
371 //      category = new PreferencesCategory(mwindow, 
372 //              thread, 
373 //              mwindow->theme->preferencescategory_x, 
374 //              mwindow->theme->preferencescategory_y);
375 //      category->create_objects();
378         add_subwindow(button = new PreferencesOK(mwindow, thread));
379         add_subwindow(new PreferencesApply(mwindow, thread));
380         add_subwindow(new PreferencesCancel(mwindow, thread));
382         set_current_dialog(thread->current_dialog);
383         show_window();
384         return 0;
387 int PreferencesWindow::update_framerate()
389         lock_window("PreferencesWindow::update_framerate");
390         if(thread->current_dialog == 0)
391         {
392                 thread->edl->session->actual_frame_rate = 
393                         mwindow->edl->session->actual_frame_rate;
394                 dialog->draw_framerate();
395                 flash();
396         }
397         unlock_window();
398         return 0;
401 int PreferencesWindow::set_current_dialog(int number)
403         thread->current_dialog = number;
404         if(dialog) delete dialog;
405         dialog = 0;
407 // Redraw category buttons
408         for(int i = 0; i < CATEGORIES; i++)
409         {
410                 if(i == number)
411                 {
412                         category_button[i]->set_images(
413                                 mwindow->theme->get_image_set("category_button_checked"));
414                 }
415                 else
416                 {
417                         category_button[i]->set_images(
418                                 mwindow->theme->get_image_set("category_button"));
419                 }
420                 category_button[i]->draw_face();
422 // Copy face to background for next button's overlap.
423 // Still can't to state changes right.
424         }
426         switch(number)
427         {
428                 case PreferencesThread::PLAYBACK:
429                         add_subwindow(dialog = new PlaybackPrefs(mwindow, this));
430                         break;
431         
432                 case PreferencesThread::RECORD:
433                         add_subwindow(dialog = new RecordPrefs(mwindow, this));
434                         break;
435         
436                 case PreferencesThread::PERFORMANCE:
437                         add_subwindow(dialog = new PerformancePrefs(mwindow, this));
438                         break;
439         
440                 case PreferencesThread::INTERFACE:
441                         add_subwindow(dialog = new InterfacePrefs(mwindow, this));
442                         break;
443         
444                 case PreferencesThread::ABOUT:
445                         add_subwindow(dialog = new AboutPrefs(mwindow, this));
446                         break;
447         }
449         if(dialog)
450         {
451                 dialog->draw_top_background(this, 0, 0, dialog->get_w(), dialog->get_h());
452                 dialog->flash();
453                 dialog->create_objects();
454         }
455         return 0;
468 PreferencesButton::PreferencesButton(MWindow *mwindow, 
469         PreferencesThread *thread, 
470         int x, 
471         int y,
472         int category,
473         char *text,
474         VFrame **images)
475  : BC_GenericButton(x, y, text, images)
477         this->mwindow = mwindow;
478         this->thread = thread;
479         this->category = category;
482 int PreferencesButton::handle_event()
484         thread->window->set_current_dialog(category);
485         return 1;
496 PreferencesDialog::PreferencesDialog(MWindow *mwindow, PreferencesWindow *pwindow)
497  : BC_SubWindow(10, 
498         40, 
499         pwindow->get_w() - 20, 
500         pwindow->get_h() - BC_GenericButton::calculate_h() - 10 - 40)
502         this->pwindow = pwindow;
503         this->mwindow = mwindow;
504         preferences = pwindow->thread->preferences;
507 PreferencesDialog::~PreferencesDialog()
511 // ============================== category window
516 PreferencesApply::PreferencesApply(MWindow *mwindow, PreferencesThread *thread)
517  : BC_GenericButton(thread->window->get_w() / 2 - BC_GenericButton::calculate_w(thread->window, _("Apply")) / 2, 
518         thread->window->get_h() - BC_GenericButton::calculate_h() - 10, 
519         _("Apply"))
521         this->mwindow = mwindow;
522         this->thread = thread;
525 int PreferencesApply::handle_event()
527         thread->apply_settings();
528         return 1;
534 PreferencesOK::PreferencesOK(MWindow *mwindow, PreferencesThread *thread)
535  : BC_GenericButton(10, 
536         thread->window->get_h() - BC_GenericButton::calculate_h() - 10,
537         _("OK"))
539         this->mwindow = mwindow;
540         this->thread = thread;
543 int PreferencesOK::keypress_event()
545         if(get_keypress() == RETURN)
546         {
547                 thread->window->set_done(0);
548                 return 1;
549         }
550         return 0;
552 int PreferencesOK::handle_event()
554         thread->window->set_done(0);
555         return 1;
560 PreferencesCancel::PreferencesCancel(MWindow *mwindow, PreferencesThread *thread)
561  : BC_GenericButton(thread->window->get_w() - BC_GenericButton::calculate_w(thread->window, _("Cancel")) - 10,
562         thread->window->get_h() - BC_GenericButton::calculate_h() - 10,
563         _("Cancel"))
565         this->mwindow = mwindow;
566         this->thread = thread;
568 int PreferencesCancel::keypress_event()
570         if(get_keypress() == ESC)
571         {
572                 thread->window->set_done(1);
573                 return 1;
574         }
575         return 0;
578 int PreferencesCancel::handle_event()
580         thread->window->set_done(1);
581         return 1;
593 PreferencesCategory::PreferencesCategory(MWindow *mwindow, PreferencesThread *thread, int x, int y)
594  : BC_PopupTextBox(thread->window, 
595                 &thread->window->categories,
596                 thread->category_to_text(thread->current_dialog),
597                 x, 
598                 y, 
599                 200,
600                 150)
602         this->mwindow = mwindow;
603         this->thread = thread;
606 PreferencesCategory::~PreferencesCategory()
610 int PreferencesCategory::handle_event()
612 SET_TRACE
613         thread->window->set_current_dialog(thread->text_to_category(get_text()));
614 SET_TRACE
615         return 1;