r802: Remove renderframfsclient and renderfarmfsserver .h and .C from Makefile.am...
[cinelerra_cv/mob.git] / cinelerra / recordgui.C
blob4afb781716287552182a88362da9c9d4fdd20760
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 "defaults.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 cancel_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 BC_OKButton(this));
406         cancel_thread = new RecordCancelThread(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         batch_list->reposition_window(batch_list->get_x(), 
545                 batch_list->get_y(),
546                 mwindow->session->rwindow_w - 20,
547                 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         flash();
555         return 1;
558 void RecordGUI::update_batch_tools()
560 //printf("RecordGUI::update_batch_tools 1\n");
561         char string[BCTEXTLEN];
562         Batch *batch = record->get_editing_batch();
563         batch_path->update(batch->get_current_asset()->path);
565 // File is open in editing batch
566 //      if(record->current_batch == record->editing_batch && record->file)
567 //              batch_path->disable();
568 //      else
569 //              batch_path->enable();
571         batch_start->update(&batch->start_day, &batch->start_time);
572         batch_duration->update(0, &batch->duration);
573         batch_source->update(batch->get_source_text());
574         batch_mode->update(Batch::mode_to_text(batch->record_mode));
575         flush();
579 RecordGUIBatches::RecordGUIBatches(Record *record, RecordGUI *gui, int x, int y, int w, int h)
580  : BC_ListBox(x, 
581                 y, 
582                 w, 
583                 h,
584                 LISTBOX_TEXT,                   // Display text list or icons
585                 gui->batches,               // Each column has an ArrayList of BC_ListBoxItems.
586                 gui->batch_titles,             // Titles for columns.  Set to 0 for no titles
587                 gui->column_widths,                // width of each column
588                 BATCH_COLUMNS,                      // Total columns.
589                 0,                    // Pixel of top of window.
590                 0,                        // If this listbox is a popup window
591                 LISTBOX_SINGLE,  // Select one item or multiple items
592                 ICON_LEFT,        // Position of icon relative to text of each item
593                 1)           // Allow dragging
595         this->record = record;
596         this->gui = gui;
597         dragging_item = 0;
600 // Do nothing for double clicks to protect active batch
601 int RecordGUIBatches::handle_event()
603         return 1;
606 int RecordGUIBatches::selection_changed()
608         if(get_selection_number(0, 0) >= 0)
609         {
610                 int i = get_selection_number(0, 0);
611                 record->change_editing_batch(get_selection_number(0, 0));
612                 if(get_cursor_x() < gui->column_widths[0])
613                 {
614                         record->batches.values[i]->enabled = 
615                                 !record->batches.values[i]->enabled;
616                         gui->update_batches();
617                 }
618         }
619         return 1;
622 int RecordGUIBatches::column_resize_event()
624         for(int i = 0; i < BATCH_COLUMNS; i++)
625         {
626                 gui->column_widths[i] = get_column_width(i);
627         }
628         return 1;
631 int RecordGUIBatches::drag_start_event()
633         if(BC_ListBox::drag_start_event())
634         {
635                 dragging_item = 1;
636                 return 1;
637         }
639         return 0;
642 int RecordGUIBatches::drag_motion_event()
644         if(BC_ListBox::drag_motion_event())
645         {
646                 return 1;
647         }
648         return 0;
651 int RecordGUIBatches::drag_stop_event()
653         if(dragging_item)
654         {
655                 int src = record->editing_batch;
656                 int dst = get_highlighted_item();
657                 Batch *src_item = record->batches.values[src];
658                 if(dst < 0) dst = record->batches.total;
660                 for(int i = src; i < record->batches.total - 1; i++)
661                 {
662                         record->batches.values[i] = record->batches.values[i + 1];
663                 }
664                 if(dst > src) dst--;
665                 
666                 for(int i = record->batches.total - 1; i > dst; i--)
667                 {
668                         record->batches.values[i] = record->batches.values[i - 1];
669                 }
670                 record->batches.values[dst] = src_item;
672                 BC_ListBox::drag_stop_event();
674                 dragging_item = 0;
675                 gui->update_batches();
676         }
689 RecordGUISave::RecordGUISave(Record *record, 
690         RecordGUI *record_gui)
691  : BC_Button(10, 
692         record_gui->get_h() - BC_WindowBase::get_resources()->ok_images[0]->get_h() - 10, 
693         BC_WindowBase::get_resources()->ok_images)
695         set_tooltip(_("Save the recording and quit."));
696         this->record = record;
697         this->gui = record_gui;
700 int RecordGUISave::handle_event()
702         gui->set_done(0);
703         return 1;
706 int RecordGUISave::keypress_event()
708 //      if(get_keypress() == RETURN)
709 //      {
710 //              handle_event();
711 //              return 1;
712 //      }
714         return 0;
717 RecordGUICancel::RecordGUICancel(Record *record, 
718         RecordGUI *record_gui)
719  : BC_Button(record_gui->get_w() - BC_WindowBase::get_resources()->cancel_images[0]->get_w() - 10, 
720         record_gui->get_h() - BC_WindowBase::get_resources()->cancel_images[0]->get_h() - 10, 
721         BC_WindowBase::get_resources()->cancel_images)
723         set_tooltip(_("Quit without pasting into project."));
724         this->record = record;
725         this->gui = record_gui;
728 int RecordGUICancel::handle_event()
730         if(!gui->cancel_thread->running())
731                 gui->cancel_thread->start();
732         return 1;
735 int RecordGUICancel::keypress_event()
737         if(get_keypress() == ESC)
738         {
739                 handle_event();
740                 return 1;
741         }
743         return 0;
746 RecordGUIStartOver::RecordGUIStartOver(Record *record, RecordGUI *record_gui, int x, int y)
747  : BC_GenericButton(x, y, _("Start Over"))
749         set_tooltip(_("Rewind the current file and erase."));
750         this->record = record;
751         this->gui = record_gui;
753 RecordGUIStartOver::~RecordGUIStartOver()
757 int RecordGUIStartOver::handle_event()
759         if(!gui->startover_thread->running())
760                 gui->startover_thread->start();
761         return 1;
764 RecordGUIFillFrames::RecordGUIFillFrames(MWindow *mwindow, Record *record, int x, int y)
765  : BC_CheckBox(x, y, record->fill_frames, _("Fill frames"))
767         this->mwindow = mwindow;
768         this->record = record;
769         set_tooltip(_("Write extra frames when behind."));
772 int RecordGUIFillFrames::handle_event()
774 // Video capture constitutively, just like audio, but only flash on screen if 1
775         record->fill_frames = get_value();
776         return 1;
779 RecordGUIMonitorVideo::RecordGUIMonitorVideo(MWindow *mwindow, Record *record, int x, int y)
780  : BC_CheckBox(x, y, record->monitor_video, _("Monitor video"))
782         this->mwindow = mwindow;
783         this->record = record;
786 int RecordGUIMonitorVideo::handle_event()
788 // Video capture constitutively, just like audio, but only flash on screen if 1
789         record->monitor_video = get_value();
790         if(record->monitor_video)
791         {
792                 unlock_window();
795                 record->record_monitor->window->lock_window("RecordGUIMonitorVideo::handle_event");
796                 record->record_monitor->window->show_window();
797                 record->record_monitor->window->raise_window();
798                 record->record_monitor->window->flush();
799                 record->record_monitor->window->unlock_window();
801                 lock_window("RecordGUIMonitorVideo::handle_event");
802                 record->video_window_open = 1;
803         }
804         return 1;
808 RecordGUIMonitorAudio::RecordGUIMonitorAudio(MWindow *mwindow, Record *record, int x, int y)
809  : BC_CheckBox(x, y, record->monitor_audio, _("Monitor audio"))
811         this->mwindow = mwindow;
812         this->record = record;
815 int RecordGUIMonitorAudio::handle_event()
817         record->monitor_audio = get_value();
818         if(record->monitor_audio)
819         {
820                 unlock_window();
823                 record->record_monitor->window->lock_window("RecordGUIMonitorAudio::handle_event");
824                 record->record_monitor->window->show_window();
825                 record->record_monitor->window->raise_window();
826                 record->record_monitor->window->flush();
827                 record->record_monitor->window->unlock_window();
830                 lock_window("RecordGUIMonitorVideo::handle_event");
831                 record->video_window_open = 1;
832         }
833         return 1;
836 RecordBatch::RecordBatch(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
837  : BC_PopupTextBox(gui, 
838                 &gui->batch_numbers,
839                 gui->batch_numbers.values[record->editing_batch]->get_text(),
840                 x, 
841                 y, 
842                 100,
843                 200)
845         this->gui = gui;
846         this->mwindow = mwindow;
847         this->record = record;
849 int RecordBatch::handle_event()
851         return 1;
854 RecordPath::RecordPath(MWindow *mwindow, Record *record, int x, int y)
855  : BC_TextBox(x, y, 200, 1, record->get_editing_batch()->get_current_asset()->path)
857         this->mwindow = mwindow;
858         this->record = record;
860 int RecordPath::handle_event()
862         strcpy(record->get_editing_batch()->assets.values[0]->path, get_text());
863         record->get_editing_batch()->calculate_news();
864         record->record_gui->update_batches();
865         return 1;
868 RecordStartType::RecordStartType(MWindow *mwindow, Record *record, int x, int y)
869  : BC_CheckBox(x, y, record->get_editing_batch()->start_type, _("Offset"))
871         this->mwindow = mwindow;
872         this->record = record;
874 int RecordStartType::handle_event()
876         return 1;
880 RecordStart::RecordStart(MWindow *mwindow, Record *record, int x, int y)
881  : TimeEntry(record->record_gui, 
882                 x, 
883                 y, 
884                 &(record->get_editing_batch()->start_day), 
885                 &(record->get_editing_batch()->start_time),
886                 TIME_HMS3)
888         this->mwindow = mwindow;
889         this->record = record;
891 int RecordStart::handle_event()
893         record->record_gui->update_batches();
894         return 1;
897 RecordDuration::RecordDuration(MWindow *mwindow, Record *record, int x, int y)
898  : TimeEntry(record->record_gui, 
899                 x, 
900                 y, 
901                 0, 
902                 &(record->get_editing_batch()->duration),
903                 TIME_HMS2)
905         this->mwindow = mwindow;
906         this->record = record;
908 int RecordDuration::handle_event()
910         record->record_gui->update_batches();
911         return 1;
914 RecordSource::RecordSource(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
915  : BC_PopupTextBox(gui, 
916         &gui->sources,
917         record->get_editing_batch()->get_source_text(),
918         x, 
919         y, 
920         200,
921         200)
923         this->mwindow = mwindow;
924         this->record = record;
925         this->gui = gui;
927 int RecordSource::handle_event()
929         record->set_channel(get_number());
930         return 1;
933 RecordMode::RecordMode(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
934  : BC_PopupTextBox(gui,
935         &gui->modes,
936         Batch::mode_to_text(record->get_editing_batch()->record_mode),
937         x,
938         y,
939         200,
940         100)
942         this->mwindow = mwindow;
943         this->record = record;
945 int RecordMode::handle_event()
947         record->get_editing_batch()->record_mode = Batch::text_to_mode(get_text());
948         record->record_gui->update_batches();
949         return 1;
952 RecordNews::RecordNews(MWindow *mwindow, Record *record, int x, int y)
953  : BC_TextBox(x, y, 200, 1, record->get_editing_batch()->news)
955         this->mwindow = mwindow;
956         this->record = record;
958 int RecordNews::handle_event()
960         return 1;
964 RecordGUINewBatch::RecordGUINewBatch(MWindow *mwindow, Record *record, int x, int y)
965  : BC_GenericButton(x, y, _("New"))
967         this->mwindow = mwindow;
968         this->record = record;
969         set_tooltip(_("Create new clip."));
971 int RecordGUINewBatch::handle_event()
973         record->new_batch();
974         record->record_gui->update_batches();
975         return 1;
979 RecordGUIDeleteBatch::RecordGUIDeleteBatch(MWindow *mwindow, Record *record, int x, int y)
980  : BC_GenericButton(x, y, _("Delete"))
982         this->mwindow = mwindow;
983         this->record = record;
984         set_tooltip(_("Delete clip."));
986 int RecordGUIDeleteBatch::handle_event()
988         record->delete_batch();
989         record->record_gui->update_batches();
990         return 1;
994 RecordGUIStartBatches::RecordGUIStartBatches(MWindow *mwindow, Record *record, int x, int y)
995  : BC_GenericButton(x, y, _("Start"))
997         this->mwindow = mwindow;
998         this->record = record;
999         set_tooltip(_("Start batch recording\nfrom the current position."));
1001 int RecordGUIStartBatches::handle_event()
1003         unlock_window();
1004         record->start_recording(0, CONTEXT_BATCH);
1005         lock_window("RecordGUIStartBatches::handle_event");
1006         return 1;
1010 RecordGUIStopbatches::RecordGUIStopbatches(MWindow *mwindow, Record *record, int x, int y)
1011  : BC_GenericButton(x, y, _("Stop"))
1013         this->mwindow = mwindow;
1014         this->record = record;
1016 int RecordGUIStopbatches::handle_event()
1018         return 1;
1022 RecordGUIActivateBatch::RecordGUIActivateBatch(MWindow *mwindow, Record *record, int x, int y)
1023  : BC_GenericButton(x, y, _("Activate"))
1025         this->mwindow = mwindow;
1026         this->record = record;
1027         set_tooltip(_("Make the highlighted\nclip active."));
1029 int RecordGUIActivateBatch::handle_event()
1031         record->activate_batch(record->editing_batch, 1);
1032         return 1;
1036 RecordGUILabel::RecordGUILabel(MWindow *mwindow, Record *record, int x, int y)
1037  : BC_GenericButton(x, y, _("Label"))
1039         this->mwindow = mwindow;
1040         this->record = record;
1041         set_underline(0);
1045 RecordGUILabel::~RecordGUILabel()
1049 int RecordGUILabel::handle_event()
1051         record->toggle_label();
1052         return 1;
1055 int RecordGUILabel::keypress_event()
1057         if(get_keypress() == 'l')
1058         {
1059                 handle_event();
1060                 return 1;
1061         }
1062         return 0;
1081 RecordCancelThread::RecordCancelThread(Record *record, RecordGUI *record_gui)
1082  : Thread(1, 0, 0)
1084         this->record = record;
1085         this->gui = record_gui;
1088 RecordCancelThread::~RecordCancelThread()
1090         if(Thread::running()) 
1091         {
1092                 window->lock_window("RecordCancelThread::~RecordCancelThread");
1093                 window->set_done(1);
1094                 window->unlock_window();
1095                 Thread::join();
1096         }
1100 void RecordCancelThread::run()
1102         if(record->prompt_cancel)
1103         {
1104                 window = new QuestionWindow(record->mwindow);
1105                 window->create_objects(_("Quit without pasting into project?"), 0);
1106                 int result = window->run_window();
1107                 if(result == 2) gui->set_done(1);
1108                 delete window;
1109         }
1110         else
1111         {
1112                 gui->set_done(1);
1113         }
1117 RecordStartoverThread::RecordStartoverThread(Record *record, RecordGUI *record_gui)
1118  : Thread(1, 0, 0)
1120         this->record = record;
1121         this->gui = record_gui;
1123 RecordStartoverThread::~RecordStartoverThread()
1125         if(Thread::running()) 
1126         {
1127                 window->lock_window("RecordStartoverThread::~RecordStartoverThread");
1128                 window->set_done(1);
1129                 window->unlock_window();
1130                 Thread::join();
1131         }
1134 void RecordStartoverThread::run()
1136         window = new QuestionWindow(record->mwindow);
1137         window->create_objects(_("Rewind batch and overwrite?"), 0);
1138         int result = window->run_window();
1139         if(result == 2) record->start_over();
1140         delete window;
1176 int RecordGUI::set_translation(int x, int y, float z)
1178         record->video_x = x;
1179         record->video_y = y;
1180         record->video_zoom = z;
1183 int RecordGUI::update_dropped_frames(long new_dropped)
1185         status_thread->update_dropped_frames(new_dropped);
1186         return 0;
1189 int RecordGUI::update_position(double new_position) 
1191         status_thread->update_position(new_position);
1192         return 0;
1195 int RecordGUI::update_clipped_samples(long new_clipped)
1197         status_thread->update_clipped_samples(new_clipped);
1198         return 0;
1201 int RecordGUI::keypress_event()
1203         return record_transport->keypress_event();
1206 void RecordGUI::update_labels(double new_position)
1208         RecordLabel *prev, *next;
1209         char string[BCTEXTLEN];
1211         for(prev = record->get_current_batch()->labels->last; 
1212                 prev; 
1213                 prev = prev->previous)
1214         {
1215                 if(prev->position <= new_position) break;
1216         }
1218         for(next = record->get_current_batch()->labels->first; 
1219                 next; 
1220                 next = next->next)
1221         {
1222                 if(next->position > new_position) break;
1223         }
1225         if(prev)
1226                 update_title(prev_label_title, 
1227                         prev->position);
1228         else
1229                 update_title(prev_label_title, -1);
1231 //      if(next)
1232 //              update_title(next_label_title, (double)next->position / record->default_asset->sample_rate);
1233 //      else
1234 //              update_title(next_label_title, -1);
1239 int RecordGUI::update_prev_label(long new_position) 
1241         update_title(prev_label_title, new_position);
1244 // int RecordGUI::update_next_label(long new_position) 
1245 // { 
1246 //      update_title(next_label_title, new_position); 
1247 // }
1248 // 
1249 int RecordGUI::update_title(BC_Title *title, double position)
1251         static char string[256];
1253         if(position > -1)
1254         {
1255                 Units::totext(string, 
1256                                 position, 
1257                                 mwindow->edl->session->time_format, 
1258                                 record->default_asset->sample_rate, 
1259                                 record->default_asset->frame_rate, 
1260                                 mwindow->edl->session->frames_per_foot);
1261         }
1262         else
1263         {
1264                 sprintf(string, "-");
1265         }
1266         lock_window("RecordGUI::update_title");
1267         title->update(string);
1268         unlock_window();
1271 int RecordGUI::update_duration_boxes()
1273         char string[1024];
1274 //      sprintf(string, "%d", engine->get_loop_hr());
1275 //      loop_hr->update(string);
1276 //      sprintf(string, "%d", engine->get_loop_min());
1277 //      loop_min->update(string);
1278 //      sprintf(string, "%d", engine->get_loop_sec());
1279 //      loop_sec->update(string);
1287 // ===================================== GUI
1293 // ================================================== modes
1295 RecordGUIModeMenu::RecordGUIModeMenu(int x, 
1296         int y, 
1297         int w, 
1298         char *text)
1299  : BC_PopupMenu(x, y, w, text)
1303 RecordGUIModeMenu::~RecordGUIModeMenu()
1305         delete linear;
1306         delete timed;
1307         delete loop;
1310 int RecordGUIModeMenu::add_items()
1312         add_item(linear = new RecordGUIMode(_("Untimed")));
1313         add_item(timed = new RecordGUIMode(_("Timed")));
1314 //      add_item(loop = new RecordGUIMode("_(Loop")));
1315         return 0;
1318 int RecordGUIModeMenu::handle_event()
1320 //      engine->set_record_mode(get_text());
1323 RecordGUIMode::RecordGUIMode(char *text)
1324  : BC_MenuItem(text)
1328 RecordGUIMode::~RecordGUIMode()
1332 int RecordGUIMode::handle_event()
1334         get_popup_menu()->set_text(get_text());
1335         get_popup_menu()->handle_event();
1336         return 1;
1343 RecordStatusThread::RecordStatusThread(MWindow *mwindow, RecordGUI *gui)
1344  : Thread(1, 0, 0)
1346         this->mwindow = mwindow;
1347         this->gui = gui;
1348         new_dropped_frames = -1;
1349         new_position = -1;
1350         new_clipped_samples = -1;
1351         input_lock = new Condition(0, "RecordStatusThread::input_lock");
1352         done = 0;
1355 RecordStatusThread::~RecordStatusThread()
1357         if(Thread::running())
1358         {
1359                 done = 1;
1360                 input_lock->unlock();
1361                 Thread::join();
1362         }
1365 void RecordStatusThread::update_dropped_frames(long value)
1367         new_dropped_frames = value;
1368         input_lock->unlock();
1371 void RecordStatusThread::update_position(double new_position)
1373         this->new_position = new_position;
1374         input_lock->unlock();
1377 void RecordStatusThread::update_clipped_samples(long new_clipped_samples)
1379         this->new_clipped_samples = new_clipped_samples;
1380         input_lock->unlock();
1383 void RecordStatusThread::run()
1385         while(!done)
1386         {
1387                 input_lock->lock("RecordStatusThread::run");
1388                 if(new_dropped_frames >= 0)
1389                 {
1390                         char string[1024];
1391                         if(gui->total_dropped_frames != new_dropped_frames)
1392                         {
1393                                 gui->total_dropped_frames = new_dropped_frames;
1394                                 sprintf(string, "%d\n", gui->total_dropped_frames);
1395                                 gui->lock_window("RecordStatusThread::run 1");
1396                                 gui->frames_dropped->update(string);
1397                                 gui->unlock_window();
1398                         }
1399                 }
1400                 
1401                 if(new_position >= 0)
1402                 {
1403                         gui->update_title(gui->position_title, new_position);
1404                         gui->update_labels(new_position);
1405                 }
1406                 
1407                 if(new_clipped_samples >= 0)
1408                 {
1409                         if(gui->total_clipped_samples != new_clipped_samples)
1410                         {
1411                                 char string[1024];
1412                                 gui->total_clipped_samples = new_clipped_samples;
1413                                 sprintf(string, "%d\n", gui->total_clipped_samples);
1414                                 gui->lock_window("RecordStatusThread::run 2");
1415                                 gui->samples_clipped->update(string);
1416                                 gui->unlock_window();
1417                         }
1418                 }
1420                 new_clipped_samples = -1;
1421                 new_dropped_frames = -1;
1422                 new_position = -1;
1423         }
1433 RecordGUIDCOffset::RecordGUIDCOffset(MWindow *mwindow, int y)
1434  : BC_Button(230, y, mwindow->theme->calibrate_data)
1438 RecordGUIDCOffset::~RecordGUIDCOffset() {}
1440 int RecordGUIDCOffset::handle_event()
1442 //      engine->calibrate_dc_offset();
1443         return 1;
1446 int RecordGUIDCOffset::keypress_event() { return 0; }
1448 RecordGUIDCOffsetText::RecordGUIDCOffsetText(char *text, int y, int number)
1449  : BC_TextBox(30, y+1, 67, 1, text, 0)
1451         this->number = number; 
1454 RecordGUIDCOffsetText::~RecordGUIDCOffsetText()
1457         
1458 int RecordGUIDCOffsetText::handle_event()
1460 //      if(!engine->is_previewing)
1461 //      {
1462 //              engine->calibrate_dc_offset(atol(get_text()), number);
1463 //      }
1464         return 1;
1467 RecordGUIReset::RecordGUIReset(MWindow *mwindow, RecordGUI *gui, int y)
1468  : BC_Button(400, y, mwindow->theme->over_button)
1469 { this->gui = gui; }
1471 RecordGUIReset::~RecordGUIReset() 
1475 int RecordGUIReset::handle_event()
1477 //      for(int i = 0; i < gui->engine->get_input_channels(); i++)
1478 //      {
1479 //              gui->meter[i]->reset_over();
1480 //      }
1481         return 1;
1484 RecordGUIResetTranslation::RecordGUIResetTranslation(MWindow *mwindow, RecordGUI *gui, int y)
1485  : BC_Button(250, y, mwindow->theme->reset_data)
1486 { this->gui = gui; }
1488 RecordGUIResetTranslation::~RecordGUIResetTranslation() 
1492 int RecordGUIResetTranslation::handle_event()
1494         gui->set_translation(0, 0, 1);
1495         return 1;
1502 RecordGUIOK::RecordGUIOK(MWindow *mwindow, int y)
1503  : BC_OKButton(50, y)
1507 RecordGUIOK::~RecordGUIOK()
1511 int RecordGUIOK::handle_event()
1513         unlock_window();
1514 //      engine->set_done(0);
1515         lock_window();
1516         return 1;