r870: Merge 2.1:
[cinelerra_cv.git] / cinelerra / recordgui.C
bloba9daafd29db4a7efba55218256765878d3775289
1 #include "asset.h"
2 #include "batch.h"
3 #include "bcsignals.h"
4 #include "browsebutton.h"
5 #include "channelpicker.h"
6 #include "clip.h"
7 #include "condition.h"
8 #include "bchash.h"
9 #include "edl.h"
10 #include "edlsession.h"
11 #include "file.h"
12 #include "filemov.h"
13 #include "filesystem.h"
14 #include "keys.h"
15 #include "language.h"
16 #include "loadmode.h"
17 #include "mwindow.h"
18 #include "mwindowgui.h"
19 #include "preferences.h"
20 #include "question.h"
21 #include "recconfirmdelete.h"
22 #include "recordgui.h"
23 #include "record.h"
24 #include "recordlabel.h"
25 #include "recordmonitor.h"
26 #include "recordtransport.h"
27 #include "recordvideo.h"
28 #include "mainsession.h"
29 #include "theme.h"
30 #include "units.h"
31 #include "videodevice.h"
33 #include <time.h>
38 RecordGUI::RecordGUI(MWindow *mwindow, Record *record)
39  : BC_Window(PROGRAM_NAME ": Recording", 
40         mwindow->session->rwindow_x, 
41         mwindow->session->rwindow_y, 
42         mwindow->session->rwindow_w, 
43         mwindow->session->rwindow_h,
44         10,
45         10,
46         1,
47         0,
48         1)
50         this->mwindow = mwindow;
51         this->record = record;
54 RecordGUI::~RecordGUI()
56 TRACE("RecordGUI::~RecordGUI 1");
57         delete status_thread;
58         delete batch_source;
59         delete batch_mode;
60         delete startover_thread;
61         delete interrupt_thread;
62         delete batch_start;
63         delete batch_duration;
64         delete load_mode;
65 TRACE("RecordGUI::~RecordGUI 2");
69 char* RecordGUI::batch_titles[] = 
71         N_("On"),
72         N_("Path"),
73         N_("News"),
74         N_("Start time"),
75         N_("Duration"),
76         N_("Source"),
77         N_("Mode")
80 void RecordGUI::load_defaults()
82         static int default_columnwidth[] =
83         {
84                 30,
85                 200,
86                 100,
87                 100,
88                 100,
89                 100,
90                 70
91         };
93         char string[BCTEXTLEN];
94         for(int i = 0; i < BATCH_COLUMNS; i++)
95         {
96                 sprintf(string, "BATCH_COLUMNWIDTH_%d", i);
97                 column_widths[i] = mwindow->defaults->get(string, default_columnwidth[i]);
98         }
101 void RecordGUI::save_defaults()
103         char string[BCTEXTLEN];
104         for(int i = 0; i < BATCH_COLUMNS; i++)
105         {
106                 sprintf(string, "BATCH_COLUMNWIDTH_%d", i);
107                 mwindow->defaults->update(string, column_widths[i]);
108         }
112 int RecordGUI::create_objects()
114         char string[BCTEXTLEN];
115         flash_color = RED;
117         status_thread = new RecordStatusThread(mwindow, this);
118         status_thread->start();
119         set_icon(mwindow->theme->get_image("record_icon"));
121         mwindow->theme->get_recordgui_sizes(this, get_w(), get_h());
122 //printf("RecordGUI::create_objects 1\n");
123         mwindow->theme->draw_rwindow_bg(this);
126         monitor_video = 0;
127         monitor_audio = 0;
128         total_dropped_frames = 0;
129         batch_list = 0;
130         update_batches();
131         modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_INFINITE)));
132         modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_TIMED)));
133 //      modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_LOOP)));
134 //      modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_SCENETOSCENE)));
136         int x = 10;
137         int y = 10;
138         int x1 = 0;
139         BC_Title *title;
140         int pad = MAX(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1), 
141                 BC_Title::calculate_h(this, "X")) + 5;
142         int button_y = 0;
144 // Curent batch
145         add_subwindow(title = new BC_Title(x, y, _("Path:")));
146         x1 = MAX(title->get_w(), x1);
147         y += pad;
148         add_subwindow(title = new BC_Title(x, y, _("Start time:")));
149         x1 = MAX(title->get_w(), x1);
150         y += pad;
151         add_subwindow(title = new BC_Title(x, y, _("Duration time:")));
152         x1 = MAX(title->get_w(), x1);
153         y += pad;
154         add_subwindow(title = new BC_Title(x, y, _("Source:")));
155         x1 = MAX(title->get_w(), x1);
156         y += pad;
157         add_subwindow(title = new BC_Title(x, y, _("Mode:")));
158         x1 = MAX(title->get_w(), x1);
159         y += pad;
160         add_subwindow(title = new BC_Title(x, y, _("Transport:")));
161         x1 = MAX(title->get_w(), x1);
162         y += pad;
164         button_y = MAX(y, button_y);
168         int x2 = 0;
169         y = 10;
170         x = x1 + 20;
171         add_subwindow(batch_path = new RecordPath(mwindow, record, x, y));
172         add_subwindow(batch_browse = new BrowseButton(mwindow, 
173                 this, 
174                 batch_path, 
175                 batch_path->get_x() + batch_path->get_w(), 
176                 y,
177                 record->default_asset->path,
178                 PROGRAM_NAME ": Record path",
179                 _("Select a file to record to:"),
180                 0));
181         x2 = MAX(x2, batch_path->get_w() + batch_browse->get_w());
182         y += pad;
183         batch_start = new RecordStart(mwindow, record, x, y);
184         batch_start->create_objects();
185         x2 = MAX(x2, batch_start->get_w());
186         y += pad;
187         batch_duration = new RecordDuration(mwindow, record, x, y);
188         batch_duration->create_objects();
189         x2 = MAX(x2, batch_duration->get_w());
190         y += pad;
191         batch_source = new RecordSource(mwindow, record, this, x, y);
192         batch_source->create_objects();
193         x2 = MAX(x2, batch_source->get_w());
194         y += pad;
195         batch_mode = new RecordMode(mwindow, record, this, x, y);
196         batch_mode->create_objects();
197         x2 = MAX(x2, batch_mode->get_w());
198         y += pad;
199         record_transport = new RecordTransport(mwindow, 
200                 record, 
201                 this, 
202                 x,
203                 y);
204         record_transport->create_objects();
205         x2 = MAX(x2, record_transport->get_w());
210 // Compression settings
211         x = x2 + x1 + 30;
212         y = 10;
213         int x3 = 0;
214         pad = BC_Title::calculate_h(this, "X") + 5;
215         add_subwindow(title = new BC_Title(x, y, _("Format:")));
216         x3 = MAX(title->get_w(), x3);
217         y += pad;
219         if(record->default_asset->audio_data)
220         {
221                 add_subwindow(title = new BC_Title(x, y, _("Audio compression:")));
222                 x3 = MAX(title->get_w(), x3);
223                 y += pad;
224                 add_subwindow(title = new BC_Title(x, y, _("Samplerate:")));
225                 x3 = MAX(title->get_w(), x3);
226                 y += pad;
227                 add_subwindow(title = new BC_Title(x, y, _("Clipped samples:")));
228                 x3 = MAX(title->get_w(), x3);
229                 y += pad;
230         }
232         if(record->default_asset->video_data)
233         {
234                 add_subwindow(title = new BC_Title(x, y, _("Video compression:")));
235                 x3 = MAX(title->get_w(), x3);
236                 y += pad;
237                 add_subwindow(title = new BC_Title(x, y, _("Framerate:")));
238                 x3 = MAX(title->get_w(), x3);
239                 y += pad;
240                 add_subwindow(title = new BC_Title(x, y, _("Frames behind:")));
241                 x3 = MAX(title->get_w(), x3);
242                 y += pad;
243         }
245         add_subwindow(title = new BC_Title(x, y, _("Position:")));
246         x3 = MAX(title->get_w(), x3);
247         y += pad;
248         add_subwindow(title = new BC_Title(x, y, _("Prev label:")));
249         x3 = MAX(title->get_w(), x3);
250         y += pad;
252         button_y = MAX(y, button_y);
253         y = 10;
254         x = x3 + x2 + x1 + 40;
256         add_subwindow(new BC_Title(x, 
257                 y, 
258                 File::formattostr(mwindow->plugindb, 
259                         record->default_asset->format), 
260                 MEDIUMFONT, 
261                 mwindow->theme->recordgui_fixed_color));
262         y += pad;
264         if(record->default_asset->audio_data)
265         {
266                 add_subwindow(new BC_Title(x, 
267                         y, 
268                         File::bitstostr(record->default_asset->bits), 
269                         MEDIUMFONT, 
270                         mwindow->theme->recordgui_fixed_color));
272                 y += pad;
273                 sprintf(string, "%d", record->default_asset->sample_rate);
274                 add_subwindow(new BC_Title(x, 
275                         y, 
276                         string, 
277                         MEDIUMFONT, 
278                         mwindow->theme->recordgui_fixed_color));
280                 y += pad;
281                 add_subwindow(samples_clipped = new BC_Title(x, 
282                         y, 
283                         "0", 
284                         MEDIUMFONT, 
285                         mwindow->theme->recordgui_variable_color));
286                 y += pad;
287         }
289         if(record->default_asset->video_data)
290         {
291                 add_subwindow(new BC_Title(x, 
292                         y, 
293                         FileMOV::compressiontostr(record->default_asset->vcodec), 
294                         MEDIUMFONT, 
295                         mwindow->theme->recordgui_fixed_color));
296         
297                 y += pad;
298                 sprintf(string, "%0.2f", record->default_asset->frame_rate);
299                 add_subwindow(new BC_Title(x, 
300                         y, 
301                         string, 
302                         MEDIUMFONT, 
303                         mwindow->theme->recordgui_fixed_color));
304         
305                 y += pad;
306                 add_subwindow(frames_dropped = new BC_Title(x, 
307                         y, 
308                         "0", 
309                         MEDIUMFONT, 
310                         mwindow->theme->recordgui_variable_color));
311                 y += pad;
312         }
314         add_subwindow(position_title = new BC_Title(x, 
315                 y, 
316                 "", 
317                 MEDIUMFONT, 
318                 mwindow->theme->recordgui_variable_color));
320         y += pad;
321         add_subwindow(prev_label_title = new BC_Title(x, 
322                 y, 
323                 _("None"), 
324                 MEDIUMFONT, 
325                 mwindow->theme->recordgui_variable_color));
327         y += pad + 10;
328         button_y = MAX(y, button_y);
329         
330         
331         
339 // Buttons
340         x = 10;
341         y = button_y;
344         add_subwindow(title = new BC_Title(x,y, _("Batches:")));
345         x += title->get_w() + 5;
346         add_subwindow(activate_batch = new RecordGUIActivateBatch(mwindow, record, x, y));
347         x += activate_batch->get_w();
348         add_subwindow(start_batches = new RecordGUIStartBatches(mwindow, record, x, y));
349         x += start_batches->get_w();
350         add_subwindow(delete_batch = new RecordGUIDeleteBatch(mwindow, record, x, y));
351         x += delete_batch->get_w();
352         add_subwindow(new_batch = new RecordGUINewBatch(mwindow, record, x, y));
353         x += new_batch->get_w();
354         add_subwindow(label_button = new RecordGUILabel(mwindow, record, x, y));
358         x = 10;
359         y += MAX(label_button->get_h(), record_transport->get_h()) + 5;
361         fill_frames = 0;
362         monitor_video = 0;
363         monitor_audio = 0;
364         if(record->default_asset->video_data) 
365         {
366                 add_subwindow(fill_frames = new RecordGUIFillFrames(mwindow, record, x, y));
367                 x += fill_frames->get_w() + 5;
368                 add_subwindow(monitor_video = new RecordGUIMonitorVideo(mwindow, record, x, y));
369                 x += monitor_video->get_w() + 5;
370         }
372         if(record->default_asset->audio_data) 
373                 add_subwindow(monitor_audio = new RecordGUIMonitorAudio(mwindow, record, x, y));
375 // Batches
376         x = 10;
377         y += 5;
378         if(fill_frames) y += fill_frames->get_h();
379         else
380         if(monitor_audio) y += monitor_audio->get_h();
382         int bottom_margin = MAX(BC_OKButton::calculate_h(), 
383                 LoadMode::calculate_h(this)) + 5;
386         add_subwindow(batch_list = new RecordGUIBatches(record, 
387                 this, 
388                 x, 
389                 y,
390                 get_w() - 20,
391                 get_h() - y - bottom_margin - 10));
392         y += batch_list->get_h() + 5;
394 // Controls
395         load_mode = new LoadMode(mwindow,
396                 this, 
397                 get_w() / 2 - mwindow->theme->loadmode_w / 2, 
398                 y, 
399                 &record->load_mode, 
400                 1);
401         load_mode->create_objects();
402         y += load_mode->get_h() + 5;
404         add_subwindow(new RecordGUIOK(record, this));
406         interrupt_thread = new EndRecordThread(record, this);
407 //      add_subwindow(new RecordGUISave(record, this));
408         add_subwindow(new RecordGUICancel(record, this));
410         startover_thread = new RecordStartoverThread(record, this);
412         return 0;
415 void RecordGUI::flash_batch()
417         if(record->current_batch < batches[0].total)
418         {
419                 if(flash_color == GREEN)
420                         flash_color = RED;
421                 else
422                         flash_color = GREEN;
424 //printf("RecordGUI::flash_batch %x\n", flash_color);
426                 for(int i = 0; i < BATCH_COLUMNS; i++)
427                 {
428                         BC_ListBoxItem *batch = batches[i].values[record->current_batch];
429                         batch->set_color(flash_color);
430                 }
431                 batch_list->update(batches,
432                         batch_titles,
433                         column_widths,
434                         BATCH_COLUMNS,
435                         batch_list->get_yposition(),
436                         batch_list->get_xposition(),
437                         batch_list->get_highlighted_item());
439                 batch_list->flush();
440         }
443 void RecordGUI::update_batches()
445         char string[BCTEXTLEN], string2[BCTEXTLEN];
446         FileSystem fs;
448         int selection_number = batch_list ? batch_list->get_selection_number(0, 0) : -1;
449         for(int j = 0; j < BATCH_COLUMNS; j++)
450         {
451                 batches[j].remove_all_objects();
452         }
454         for(int i = 0; i < record->batches.total; i++)
455         {
456                 Batch *batch = record->batches.values[i];
457                 int color = (i == record->current_batch) ? RED : BLACK;
458                 if(batch->waiting && time(0) & 0x1) color = GREEN;
460                 batches[0].append(new BC_ListBoxItem((char*)(batch->enabled ? "X" : " "), color));
461                 batches[1].append(new BC_ListBoxItem(batch->get_current_asset()->path, color));
462                 sprintf(string, "%s", batch->news);
463                 batches[2].append(new BC_ListBoxItem(string, RED));
464                 Units::totext(string2, 
465                                 batch->start_time, 
466                                 TIME_HMS, 
467                                 record->default_asset->sample_rate,
468                                 record->default_asset->frame_rate, 
469                                 mwindow->edl->session->frames_per_foot);
470                 sprintf(string, "%s %s", TimeEntry::day_table[batch->start_day], string2);
472                 batches[3].append(new BC_ListBoxItem(string, color));
473                 Units::totext(string, 
474                                 batch->duration, 
475                                 TIME_HMS, 
476                                 record->default_asset->sample_rate,
477                                 record->default_asset->frame_rate, 
478                                 mwindow->edl->session->frames_per_foot);
479                 batches[4].append(new BC_ListBoxItem(string, color));
480                 record->source_to_text(string, batch);
481                 batches[5].append(new BC_ListBoxItem(string, color));
482                 sprintf(string, "%s", Batch::mode_to_text(batch->record_mode));
483                 batches[6].append(new BC_ListBoxItem(string, color));
484                 
485                 if(i == selection_number)
486                 {
487                         for(int j = 0; j < BATCH_COLUMNS; j++)
488                         {
489                                 batches[j].values[i]->set_selected(1);
490                         }
491                 }
492         }
494         if(batch_list)
495         {
496                 batch_list->update(batches,
497                         batch_titles,
498                         column_widths,
499                         BATCH_COLUMNS,
500                         batch_list->get_yposition(),
501                         batch_list->get_xposition(),
502                         record->editing_batch,
503                         1);
504         }
505         flush();
508 void RecordGUI::update_batch_sources()
510 //printf("RecordGUI::update_batch_sources 1\n");
511         if(record->record_monitor->window->channel_picker)
512                 batch_source->update_list(
513                         &record->record_monitor->window->channel_picker->channel_listitems);
514 //printf("RecordGUI::update_batch_sources 2\n");
517 int RecordGUI::translation_event()
519         mwindow->session->rwindow_x = get_x();
520         mwindow->session->rwindow_y = get_y();
521         return 0;
525 int RecordGUI::resize_event(int w, int h)
527         int x, y, x1;
529 // Recompute batch list based on previous extents
530         int bottom_margin = mwindow->session->rwindow_h - 
531                 batch_list->get_y() - 
532                 batch_list->get_h();
533         int mode_margin = mwindow->session->rwindow_h - load_mode->get_y();
534         mwindow->session->rwindow_x = get_x();
535         mwindow->session->rwindow_y = get_y();
536         mwindow->session->rwindow_w = w;
537         mwindow->session->rwindow_h = h;
538         mwindow->theme->get_recordgui_sizes(this, w, h);
539         mwindow->theme->draw_rwindow_bg(this);
542         int new_h = mwindow->session->rwindow_h - bottom_margin - batch_list->get_y();
543         if(new_h < 10) new_h = 10;
544 printf("RecordGUI::resize_event 1 %d\n", mwindow->session->rwindow_h - bottom_margin - batch_list->get_y());
545         batch_list->reposition_window(batch_list->get_x(), 
546                 batch_list->get_y(),
547                 mwindow->session->rwindow_w - 20,
548                 mwindow->session->rwindow_h - bottom_margin - batch_list->get_y());
550         load_mode->reposition_window(mwindow->session->rwindow_w / 2 - 
551                         mwindow->theme->loadmode_w / 2,
552                 mwindow->session->rwindow_h - mode_margin);
554         
556         flash();
557         return 1;
560 void RecordGUI::update_batch_tools()
562 //printf("RecordGUI::update_batch_tools 1\n");
563         char string[BCTEXTLEN];
564         Batch *batch = record->get_editing_batch();
565         batch_path->update(batch->get_current_asset()->path);
567 // File is open in editing batch
568 //      if(record->current_batch == record->editing_batch && record->file)
569 //              batch_path->disable();
570 //      else
571 //              batch_path->enable();
573         batch_start->update(&batch->start_day, &batch->start_time);
574         batch_duration->update(0, &batch->duration);
575         batch_source->update(batch->get_source_text());
576         batch_mode->update(Batch::mode_to_text(batch->record_mode));
577         flush();
581 RecordGUIBatches::RecordGUIBatches(Record *record, RecordGUI *gui, int x, int y, int w, int h)
582  : BC_ListBox(x, 
583                 y, 
584                 w, 
585                 h,
586                 LISTBOX_TEXT,                   // Display text list or icons
587                 gui->batches,               // Each column has an ArrayList of BC_ListBoxItems.
588                 gui->batch_titles,             // Titles for columns.  Set to 0 for no titles
589                 gui->column_widths,                // width of each column
590                 BATCH_COLUMNS,                      // Total columns.
591                 0,                    // Pixel of top of window.
592                 0,                        // If this listbox is a popup window
593                 LISTBOX_SINGLE,  // Select one item or multiple items
594                 ICON_LEFT,        // Position of icon relative to text of each item
595                 1)           // Allow dragging
597         this->record = record;
598         this->gui = gui;
599         dragging_item = 0;
602 // Do nothing for double clicks to protect active batch
603 int RecordGUIBatches::handle_event()
605         return 1;
608 int RecordGUIBatches::selection_changed()
610         if(get_selection_number(0, 0) >= 0)
611         {
612                 int i = get_selection_number(0, 0);
613                 record->change_editing_batch(get_selection_number(0, 0));
614                 if(get_cursor_x() < gui->column_widths[0])
615                 {
616                         record->batches.values[i]->enabled = 
617                                 !record->batches.values[i]->enabled;
618                         gui->update_batches();
619                 }
620         }
621         return 1;
624 int RecordGUIBatches::column_resize_event()
626         for(int i = 0; i < BATCH_COLUMNS; i++)
627         {
628                 gui->column_widths[i] = get_column_width(i);
629         }
630         return 1;
633 int RecordGUIBatches::drag_start_event()
635         if(BC_ListBox::drag_start_event())
636         {
637                 dragging_item = 1;
638                 return 1;
639         }
641         return 0;
644 int RecordGUIBatches::drag_motion_event()
646         if(BC_ListBox::drag_motion_event())
647         {
648                 return 1;
649         }
650         return 0;
653 int RecordGUIBatches::drag_stop_event()
655         if(dragging_item)
656         {
657                 int src = record->editing_batch;
658                 int dst = get_highlighted_item();
659                 Batch *src_item = record->batches.values[src];
660                 if(dst < 0) dst = record->batches.total;
662                 for(int i = src; i < record->batches.total - 1; i++)
663                 {
664                         record->batches.values[i] = record->batches.values[i + 1];
665                 }
666                 if(dst > src) dst--;
667                 
668                 for(int i = record->batches.total - 1; i > dst; i--)
669                 {
670                         record->batches.values[i] = record->batches.values[i - 1];
671                 }
672                 record->batches.values[dst] = src_item;
674                 BC_ListBox::drag_stop_event();
676                 dragging_item = 0;
677                 gui->update_batches();
678         }
691 RecordGUISave::RecordGUISave(Record *record, 
692         RecordGUI *record_gui)
693  : BC_Button(10, 
694         record_gui->get_h() - BC_WindowBase::get_resources()->ok_images[0]->get_h() - 10, 
695         BC_WindowBase::get_resources()->ok_images)
697         set_tooltip(_("Save the recording and quit."));
698         this->record = record;
699         this->gui = record_gui;
702 int RecordGUISave::handle_event()
704         gui->set_done(0);
705         return 1;
708 int RecordGUISave::keypress_event()
710 //      if(get_keypress() == RETURN)
711 //      {
712 //              handle_event();
713 //              return 1;
714 //      }
716         return 0;
719 RecordGUICancel::RecordGUICancel(Record *record, 
720         RecordGUI *record_gui)
721  : BC_CancelButton(record_gui)
723         set_tooltip(_("Quit without pasting into project."));
724         this->record = record;
725         this->gui = record_gui;
728 int RecordGUICancel::handle_event()
730         gui->interrupt_thread->start(0);
731         return 1;
734 int RecordGUICancel::keypress_event()
736         if(get_keypress() == ESC)
737         {
738                 handle_event();
739                 return 1;
740         }
742         return 0;
749 RecordGUIOK::RecordGUIOK(Record *record, 
750         RecordGUI *record_gui)
751  : BC_OKButton(record_gui)
753         set_tooltip(_("Quit and paste into project."));
754         this->record = record;
755         this->gui = record_gui;
758 int RecordGUIOK::handle_event()
760         gui->interrupt_thread->start(1);
761         return 1;
771 RecordGUIStartOver::RecordGUIStartOver(Record *record, RecordGUI *record_gui, int x, int y)
772  : BC_GenericButton(x, y, _("Start Over"))
774         set_tooltip(_("Rewind the current file and erase."));
775         this->record = record;
776         this->gui = record_gui;
778 RecordGUIStartOver::~RecordGUIStartOver()
782 int RecordGUIStartOver::handle_event()
784         if(!gui->startover_thread->running())
785                 gui->startover_thread->start();
786         return 1;
789 RecordGUIFillFrames::RecordGUIFillFrames(MWindow *mwindow, Record *record, int x, int y)
790  : BC_CheckBox(x, y, record->fill_frames, _("Fill frames"))
792         this->mwindow = mwindow;
793         this->record = record;
794         set_tooltip(_("Write extra frames when behind."));
797 int RecordGUIFillFrames::handle_event()
799 // Video capture constitutively, just like audio, but only flash on screen if 1
800         record->fill_frames = get_value();
801         return 1;
804 RecordGUIMonitorVideo::RecordGUIMonitorVideo(MWindow *mwindow, Record *record, int x, int y)
805  : BC_CheckBox(x, y, record->monitor_video, _("Monitor video"))
807         this->mwindow = mwindow;
808         this->record = record;
811 int RecordGUIMonitorVideo::handle_event()
813 // Video capture constitutively, just like audio, but only flash on screen if 1
814         record->monitor_video = get_value();
815         if(record->monitor_video)
816         {
817                 unlock_window();
820                 record->record_monitor->window->lock_window("RecordGUIMonitorVideo::handle_event");
821                 record->record_monitor->window->show_window();
822                 record->record_monitor->window->raise_window();
823                 record->record_monitor->window->flush();
824                 record->record_monitor->window->unlock_window();
826                 lock_window("RecordGUIMonitorVideo::handle_event");
827                 record->video_window_open = 1;
828         }
829         return 1;
833 RecordGUIMonitorAudio::RecordGUIMonitorAudio(MWindow *mwindow, Record *record, int x, int y)
834  : BC_CheckBox(x, y, record->monitor_audio, _("Monitor audio"))
836         this->mwindow = mwindow;
837         this->record = record;
840 int RecordGUIMonitorAudio::handle_event()
842         record->monitor_audio = get_value();
843         if(record->monitor_audio)
844         {
845                 unlock_window();
848                 record->record_monitor->window->lock_window("RecordGUIMonitorAudio::handle_event");
849                 record->record_monitor->window->show_window();
850                 record->record_monitor->window->raise_window();
851                 record->record_monitor->window->flush();
852                 record->record_monitor->window->unlock_window();
855                 lock_window("RecordGUIMonitorVideo::handle_event");
856                 record->video_window_open = 1;
857         }
858         return 1;
861 RecordBatch::RecordBatch(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
862  : BC_PopupTextBox(gui, 
863                 &gui->batch_numbers,
864                 gui->batch_numbers.values[record->editing_batch]->get_text(),
865                 x, 
866                 y, 
867                 100,
868                 200)
870         this->gui = gui;
871         this->mwindow = mwindow;
872         this->record = record;
874 int RecordBatch::handle_event()
876         return 1;
879 RecordPath::RecordPath(MWindow *mwindow, Record *record, int x, int y)
880  : BC_TextBox(x, y, 200, 1, record->get_editing_batch()->get_current_asset()->path)
882         this->mwindow = mwindow;
883         this->record = record;
885 int RecordPath::handle_event()
887         strcpy(record->get_editing_batch()->assets.values[0]->path, get_text());
888         record->get_editing_batch()->calculate_news();
889         record->record_gui->update_batches();
890         return 1;
893 RecordStartType::RecordStartType(MWindow *mwindow, Record *record, int x, int y)
894  : BC_CheckBox(x, y, record->get_editing_batch()->start_type, _("Offset"))
896         this->mwindow = mwindow;
897         this->record = record;
899 int RecordStartType::handle_event()
901         return 1;
905 RecordStart::RecordStart(MWindow *mwindow, Record *record, int x, int y)
906  : TimeEntry(record->record_gui, 
907                 x, 
908                 y, 
909                 &(record->get_editing_batch()->start_day), 
910                 &(record->get_editing_batch()->start_time),
911                 TIME_HMS3)
913         this->mwindow = mwindow;
914         this->record = record;
916 int RecordStart::handle_event()
918         record->record_gui->update_batches();
919         return 1;
922 RecordDuration::RecordDuration(MWindow *mwindow, Record *record, int x, int y)
923  : TimeEntry(record->record_gui, 
924                 x, 
925                 y, 
926                 0, 
927                 &(record->get_editing_batch()->duration),
928                 TIME_HMS2)
930         this->mwindow = mwindow;
931         this->record = record;
933 int RecordDuration::handle_event()
935         record->record_gui->update_batches();
936         return 1;
939 RecordSource::RecordSource(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
940  : BC_PopupTextBox(gui, 
941         &gui->sources,
942         record->get_editing_batch()->get_source_text(),
943         x, 
944         y, 
945         200,
946         200)
948         this->mwindow = mwindow;
949         this->record = record;
950         this->gui = gui;
952 int RecordSource::handle_event()
954         record->set_channel(get_number());
955         return 1;
958 RecordMode::RecordMode(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
959  : BC_PopupTextBox(gui,
960         &gui->modes,
961         Batch::mode_to_text(record->get_editing_batch()->record_mode),
962         x,
963         y,
964         200,
965         100)
967         this->mwindow = mwindow;
968         this->record = record;
970 int RecordMode::handle_event()
972         record->get_editing_batch()->record_mode = Batch::text_to_mode(get_text());
973         record->record_gui->update_batches();
974         return 1;
977 RecordNews::RecordNews(MWindow *mwindow, Record *record, int x, int y)
978  : BC_TextBox(x, y, 200, 1, record->get_editing_batch()->news)
980         this->mwindow = mwindow;
981         this->record = record;
983 int RecordNews::handle_event()
985         return 1;
989 RecordGUINewBatch::RecordGUINewBatch(MWindow *mwindow, Record *record, int x, int y)
990  : BC_GenericButton(x, y, _("New"))
992         this->mwindow = mwindow;
993         this->record = record;
994         set_tooltip(_("Create new clip."));
996 int RecordGUINewBatch::handle_event()
998         record->new_batch();
999         record->record_gui->update_batches();
1000         return 1;
1004 RecordGUIDeleteBatch::RecordGUIDeleteBatch(MWindow *mwindow, Record *record, int x, int y)
1005  : BC_GenericButton(x, y, _("Delete"))
1007         this->mwindow = mwindow;
1008         this->record = record;
1009         set_tooltip(_("Delete clip."));
1011 int RecordGUIDeleteBatch::handle_event()
1013         record->delete_batch();
1014         record->record_gui->update_batches();
1015         return 1;
1019 RecordGUIStartBatches::RecordGUIStartBatches(MWindow *mwindow, Record *record, int x, int y)
1020  : BC_GenericButton(x, y, _("Start"))
1022         this->mwindow = mwindow;
1023         this->record = record;
1024         set_tooltip(_("Start batch recording\nfrom the current position."));
1026 int RecordGUIStartBatches::handle_event()
1028         unlock_window();
1029         record->start_recording(0, CONTEXT_BATCH);
1030         lock_window("RecordGUIStartBatches::handle_event");
1031         return 1;
1035 RecordGUIStopbatches::RecordGUIStopbatches(MWindow *mwindow, Record *record, int x, int y)
1036  : BC_GenericButton(x, y, _("Stop"))
1038         this->mwindow = mwindow;
1039         this->record = record;
1041 int RecordGUIStopbatches::handle_event()
1043         return 1;
1047 RecordGUIActivateBatch::RecordGUIActivateBatch(MWindow *mwindow, Record *record, int x, int y)
1048  : BC_GenericButton(x, y, _("Activate"))
1050         this->mwindow = mwindow;
1051         this->record = record;
1052         set_tooltip(_("Make the highlighted\nclip active."));
1054 int RecordGUIActivateBatch::handle_event()
1056         record->activate_batch(record->editing_batch, 1);
1057         return 1;
1061 RecordGUILabel::RecordGUILabel(MWindow *mwindow, Record *record, int x, int y)
1062  : BC_GenericButton(x, y, _("Label"))
1064         this->mwindow = mwindow;
1065         this->record = record;
1066         set_underline(0);
1070 RecordGUILabel::~RecordGUILabel()
1074 int RecordGUILabel::handle_event()
1076         record->toggle_label();
1077         return 1;
1080 int RecordGUILabel::keypress_event()
1082         if(get_keypress() == 'l')
1083         {
1084                 handle_event();
1085                 return 1;
1086         }
1087         return 0;
1106 EndRecordThread::EndRecordThread(Record *record, RecordGUI *record_gui)
1107  : Thread(1, 0, 0)
1109         this->record = record;
1110         this->gui = record_gui;
1111         is_ok = 0;
1114 EndRecordThread::~EndRecordThread()
1116         if(Thread::running()) 
1117         {
1118                 window->lock_window("EndRecordThread::~EndRecordThread");
1119                 window->set_done(1);
1120                 window->unlock_window();
1121                 Thread::join();
1122         }
1125 void EndRecordThread::start(int is_ok)
1127         this->is_ok = is_ok;
1128         if(record->capture_state == IS_RECORDING)
1129         {
1130                 if(!running())          
1131                         Thread::start();
1132         }
1133         else
1134         {
1135                 gui->set_done(!is_ok);
1136         }
1139 void EndRecordThread::run()
1141         window = new QuestionWindow(record->mwindow);
1142         window->create_objects(_("Interrupt recording in progress?"), 0);
1143         int result = window->run_window();
1144         delete window;
1145         if(result == 2) gui->set_done(!is_ok);
1149 RecordStartoverThread::RecordStartoverThread(Record *record, RecordGUI *record_gui)
1150  : Thread(1, 0, 0)
1152         this->record = record;
1153         this->gui = record_gui;
1155 RecordStartoverThread::~RecordStartoverThread()
1157         if(Thread::running()) 
1158         {
1159                 window->lock_window("RecordStartoverThread::~RecordStartoverThread");
1160                 window->set_done(1);
1161                 window->unlock_window();
1162                 Thread::join();
1163         }
1166 void RecordStartoverThread::run()
1168         window = new QuestionWindow(record->mwindow);
1169         window->create_objects(_("Rewind batch and overwrite?"), 0);
1170         int result = window->run_window();
1171         if(result == 2) record->start_over();
1172         delete window;
1208 int RecordGUI::set_translation(int x, int y, float z)
1210         record->video_x = x;
1211         record->video_y = y;
1212         record->video_zoom = z;
1215 int RecordGUI::update_dropped_frames(long new_dropped)
1217         status_thread->update_dropped_frames(new_dropped);
1218         return 0;
1221 int RecordGUI::update_position(double new_position) 
1223         status_thread->update_position(new_position);
1224         return 0;
1227 int RecordGUI::update_clipped_samples(long new_clipped)
1229         status_thread->update_clipped_samples(new_clipped);
1230         return 0;
1233 int RecordGUI::keypress_event()
1235         return record_transport->keypress_event();
1238 void RecordGUI::update_labels(double new_position)
1240         RecordLabel *prev, *next;
1241         char string[BCTEXTLEN];
1243         for(prev = record->get_current_batch()->labels->last; 
1244                 prev; 
1245                 prev = prev->previous)
1246         {
1247                 if(prev->position <= new_position) break;
1248         }
1250         for(next = record->get_current_batch()->labels->first; 
1251                 next; 
1252                 next = next->next)
1253         {
1254                 if(next->position > new_position) break;
1255         }
1257         if(prev)
1258                 update_title(prev_label_title, 
1259                         prev->position);
1260         else
1261                 update_title(prev_label_title, -1);
1263 //      if(next)
1264 //              update_title(next_label_title, (double)next->position / record->default_asset->sample_rate);
1265 //      else
1266 //              update_title(next_label_title, -1);
1271 int RecordGUI::update_prev_label(long new_position) 
1273         update_title(prev_label_title, new_position);
1276 // int RecordGUI::update_next_label(long new_position) 
1277 // { 
1278 //      update_title(next_label_title, new_position); 
1279 // }
1280 // 
1281 int RecordGUI::update_title(BC_Title *title, double position)
1283         static char string[256];
1285         if(position > -1)
1286         {
1287                 Units::totext(string, 
1288                                 position, 
1289                                 mwindow->edl->session->time_format, 
1290                                 record->default_asset->sample_rate, 
1291                                 record->default_asset->frame_rate, 
1292                                 mwindow->edl->session->frames_per_foot);
1293         }
1294         else
1295         {
1296                 sprintf(string, "-");
1297         }
1298         lock_window("RecordGUI::update_title");
1299         title->update(string);
1300         unlock_window();
1303 int RecordGUI::update_duration_boxes()
1305         char string[1024];
1306 //      sprintf(string, "%d", engine->get_loop_hr());
1307 //      loop_hr->update(string);
1308 //      sprintf(string, "%d", engine->get_loop_min());
1309 //      loop_min->update(string);
1310 //      sprintf(string, "%d", engine->get_loop_sec());
1311 //      loop_sec->update(string);
1319 // ===================================== GUI
1325 // ================================================== modes
1327 RecordGUIModeMenu::RecordGUIModeMenu(int x, 
1328         int y, 
1329         int w, 
1330         char *text)
1331  : BC_PopupMenu(x, y, w, text)
1335 RecordGUIModeMenu::~RecordGUIModeMenu()
1337         delete linear;
1338         delete timed;
1339         delete loop;
1342 int RecordGUIModeMenu::add_items()
1344         add_item(linear = new RecordGUIMode(_("Untimed")));
1345         add_item(timed = new RecordGUIMode(_("Timed")));
1346 //      add_item(loop = new RecordGUIMode("_(Loop")));
1347         return 0;
1350 int RecordGUIModeMenu::handle_event()
1352 //      engine->set_record_mode(get_text());
1355 RecordGUIMode::RecordGUIMode(char *text)
1356  : BC_MenuItem(text)
1360 RecordGUIMode::~RecordGUIMode()
1364 int RecordGUIMode::handle_event()
1366         get_popup_menu()->set_text(get_text());
1367         get_popup_menu()->handle_event();
1368         return 1;
1375 RecordStatusThread::RecordStatusThread(MWindow *mwindow, RecordGUI *gui)
1376  : Thread(1, 0, 0)
1378         this->mwindow = mwindow;
1379         this->gui = gui;
1380         new_dropped_frames = -1;
1381         new_position = -1;
1382         new_clipped_samples = -1;
1383         input_lock = new Condition(0, "RecordStatusThread::input_lock");
1384         done = 0;
1387 RecordStatusThread::~RecordStatusThread()
1389         if(Thread::running())
1390         {
1391                 done = 1;
1392                 input_lock->unlock();
1393                 Thread::join();
1394         }
1397 void RecordStatusThread::update_dropped_frames(long value)
1399         new_dropped_frames = value;
1400         input_lock->unlock();
1403 void RecordStatusThread::update_position(double new_position)
1405         this->new_position = new_position;
1406         input_lock->unlock();
1409 void RecordStatusThread::update_clipped_samples(long new_clipped_samples)
1411         this->new_clipped_samples = new_clipped_samples;
1412         input_lock->unlock();
1415 void RecordStatusThread::run()
1417         while(!done)
1418         {
1419                 input_lock->lock("RecordStatusThread::run");
1420                 if(new_dropped_frames >= 0)
1421                 {
1422                         char string[1024];
1423                         if(gui->total_dropped_frames != new_dropped_frames)
1424                         {
1425                                 gui->total_dropped_frames = new_dropped_frames;
1426                                 sprintf(string, "%d\n", gui->total_dropped_frames);
1427                                 gui->lock_window("RecordStatusThread::run 1");
1428                                 gui->frames_dropped->update(string);
1429                                 gui->unlock_window();
1430                         }
1431                 }
1432                 
1433                 if(new_position >= 0)
1434                 {
1435                         gui->update_title(gui->position_title, new_position);
1436                         gui->update_labels(new_position);
1437                 }
1438                 
1439                 if(new_clipped_samples >= 0)
1440                 {
1441                         if(gui->total_clipped_samples != new_clipped_samples)
1442                         {
1443                                 char string[1024];
1444                                 gui->total_clipped_samples = new_clipped_samples;
1445                                 sprintf(string, "%d\n", gui->total_clipped_samples);
1446                                 gui->lock_window("RecordStatusThread::run 2");
1447                                 gui->samples_clipped->update(string);
1448                                 gui->unlock_window();
1449                         }
1450                 }
1452                 new_clipped_samples = -1;
1453                 new_dropped_frames = -1;
1454                 new_position = -1;
1455         }
1465 RecordGUIDCOffset::RecordGUIDCOffset(MWindow *mwindow, int y)
1466  : BC_Button(230, y, mwindow->theme->calibrate_data)
1470 RecordGUIDCOffset::~RecordGUIDCOffset() {}
1472 int RecordGUIDCOffset::handle_event()
1474 //      engine->calibrate_dc_offset();
1475         return 1;
1478 int RecordGUIDCOffset::keypress_event() { return 0; }
1480 RecordGUIDCOffsetText::RecordGUIDCOffsetText(char *text, int y, int number)
1481  : BC_TextBox(30, y+1, 67, 1, text, 0)
1483         this->number = number; 
1486 RecordGUIDCOffsetText::~RecordGUIDCOffsetText()
1489         
1490 int RecordGUIDCOffsetText::handle_event()
1492 //      if(!engine->is_previewing)
1493 //      {
1494 //              engine->calibrate_dc_offset(atol(get_text()), number);
1495 //      }
1496         return 1;
1499 RecordGUIReset::RecordGUIReset(MWindow *mwindow, RecordGUI *gui, int y)
1500  : BC_Button(400, y, mwindow->theme->over_button)
1501 { this->gui = gui; }
1503 RecordGUIReset::~RecordGUIReset() 
1507 int RecordGUIReset::handle_event()
1509 //      for(int i = 0; i < gui->engine->get_input_channels(); i++)
1510 //      {
1511 //              gui->meter[i]->reset_over();
1512 //      }
1513         return 1;
1516 RecordGUIResetTranslation::RecordGUIResetTranslation(MWindow *mwindow, RecordGUI *gui, int y)
1517  : BC_Button(250, y, mwindow->theme->reset_data)
1518 { this->gui = gui; }
1520 RecordGUIResetTranslation::~RecordGUIResetTranslation() 
1524 int RecordGUIResetTranslation::handle_event()
1526         gui->set_translation(0, 0, 1);
1527         return 1;