r370: Heroine Virutal's official release 1.2.1
[cinelerra_cv/mob.git] / hvirtual / cinelerra / recordgui.C
blob5fd071495cff4147b0ddcab308ec89bf32bb0b2a
1 #include "asset.h"
2 #include "batch.h"
3 #include "bcsignals.h"
4 #include "browsebutton.h"
5 #include "channelpicker.h"
6 #include "condition.h"
7 #include "defaults.h"
8 #include "edl.h"
9 #include "edlsession.h"
10 #include "file.h"
11 #include "filemov.h"
12 #include "filesystem.h"
13 #include "keys.h"
14 #include "language.h"
15 #include "loadmode.h"
16 #include "mwindow.h"
17 #include "mwindowgui.h"
18 #include "preferences.h"
19 #include "question.h"
20 #include "recconfirmdelete.h"
21 #include "recordgui.h"
22 #include "record.h"
23 #include "recordlabel.h"
24 #include "recordmonitor.h"
25 #include "recordtransport.h"
26 #include "recordvideo.h"
27 #include "mainsession.h"
28 #include "theme.h"
29 #include "units.h"
30 #include "videodevice.h"
32 #include <time.h>
37 RecordGUI::RecordGUI(MWindow *mwindow, Record *record)
38  : BC_Window(PROGRAM_NAME ": Recording", 
39         mwindow->session->rwindow_x, 
40         mwindow->session->rwindow_y, 
41         mwindow->session->rwindow_w, 
42         mwindow->session->rwindow_h,
43         10,
44         10,
45         1,
46         0,
47         1)
49         this->mwindow = mwindow;
50         this->record = record;
53 RecordGUI::~RecordGUI()
55 TRACE("RecordGUI::~RecordGUI 1");
56         delete status_thread;
57         delete batch_source;
58         delete batch_mode;
59         delete startover_thread;
60         delete cancel_thread;
61         delete batch_start;
62         delete batch_duration;
63         delete load_mode;
64 TRACE("RecordGUI::~RecordGUI 2");
68 char* RecordGUI::batch_titles[] = 
70         N_("On"),
71         N_("Path"),
72         N_("News"),
73         N_("Start time"),
74         N_("Duration"),
75         N_("Source"),
76         N_("Mode")
79 void RecordGUI::load_defaults()
81         static int default_columnwidth[] =
82         {
83                 30,
84                 200,
85                 100,
86                 100,
87                 100,
88                 100,
89                 70
90         };
92         char string[BCTEXTLEN];
93         for(int i = 0; i < BATCH_COLUMNS; i++)
94         {
95                 sprintf(string, "BATCH_COLUMNWIDTH_%d", i);
96                 column_widths[i] = mwindow->defaults->get(string, default_columnwidth[i]);
97         }
100 void RecordGUI::save_defaults()
102         char string[BCTEXTLEN];
103         for(int i = 0; i < BATCH_COLUMNS; i++)
104         {
105                 sprintf(string, "BATCH_COLUMNWIDTH_%d", i);
106                 mwindow->defaults->update(string, column_widths[i]);
107         }
111 int RecordGUI::create_objects()
113         char string[BCTEXTLEN];
114         flash_color = RED;
116         status_thread = new RecordStatusThread(mwindow, this);
117         status_thread->start();
118         set_icon(mwindow->theme->record_icon);
120         mwindow->theme->get_recordgui_sizes(this, get_w(), get_h());
121 //printf("RecordGUI::create_objects 1\n");
122         mwindow->theme->draw_rwindow_bg(this);
125         monitor_video = 0;
126         monitor_audio = 0;
127         total_dropped_frames = 0;
128         batch_list = 0;
129         update_batches();
130         modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_INFINITE)));
131         modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_TIMED)));
132 //      modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_LOOP)));
133 //      modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_SCENETOSCENE)));
135 // Status
136         int x = mwindow->theme->recordgui_status_x;
137         int y = mwindow->theme->recordgui_status_y;
138         int x1 = mwindow->theme->recordgui_status_x2;
140         add_subwindow(new BC_Title(x, y, _("Format:")));
141         add_subwindow(new BC_Title(x1, 
142                 y, 
143                 File::formattostr(mwindow->plugindb, 
144                         record->default_asset->format), 
145                 MEDIUMFONT, 
146                 mwindow->theme->recordgui_fixed_color));
148         if(record->default_asset->audio_data)
149         {
150                 y += 20;
151                 add_subwindow(new BC_Title(x, y, _("Audio compression:")));
152                 add_subwindow(new BC_Title(x1, 
153                         y, 
154                         File::bitstostr(record->default_asset->bits), 
155                         MEDIUMFONT, 
156                         mwindow->theme->recordgui_fixed_color));
158                 y += 20;
159                 add_subwindow(new BC_Title(x, y, _("Samplerate:")));
160                 sprintf(string, "%d", record->default_asset->sample_rate);
161                 add_subwindow(new BC_Title(x1, 
162                         y, 
163                         string, 
164                         MEDIUMFONT, 
165                         mwindow->theme->recordgui_fixed_color));
167                 y += 20;
168                 add_subwindow(new BC_Title(x, y, _("Clipped samples:")));
169                 add_subwindow(samples_clipped = new BC_Title(x1, 
170                         y, 
171                         "0", 
172                         MEDIUMFONT, 
173                         mwindow->theme->recordgui_variable_color));
174         }
176         if(record->default_asset->video_data)
177         {
178                 y += 20;
179                 add_subwindow(new BC_Title(x, y, _("Video compression:")));
180                 add_subwindow(new BC_Title(x1, 
181                         y, 
182                         FileMOV::compressiontostr(record->default_asset->vcodec), 
183                         MEDIUMFONT, 
184                         mwindow->theme->recordgui_fixed_color));
185         
186                 y += 20;
187                 add_subwindow(new BC_Title(x, y, _("Framerate:")));
188                 sprintf(string, "%0.2f", record->default_asset->frame_rate);
189                 add_subwindow(new BC_Title(x1, 
190                         y, 
191                         string, 
192                         MEDIUMFONT, 
193                         mwindow->theme->recordgui_fixed_color));
194         
195                 y += 20;
196                 add_subwindow(new BC_Title(x, y, _("Frames behind:")));
197                 add_subwindow(frames_dropped = new BC_Title(x1, 
198                         y, 
199                         "0", 
200                         MEDIUMFONT, 
201                         mwindow->theme->recordgui_variable_color));
202         }
204         y += 20;
205         add_subwindow(new BC_Title(x, y, _("Position:")));
206         add_subwindow(position_title = new BC_Title(x1, 
207                 y, 
208                 "", 
209                 MEDIUMFONT, 
210                 mwindow->theme->recordgui_variable_color));
212         y += 20;
213         add_subwindow(new BC_Title(x, y, _("Prev label:")));
214         add_subwindow(prev_label_title = new BC_Title(x1, 
215                 y, 
216                 _("None"), 
217                 MEDIUMFONT, 
218                 mwindow->theme->recordgui_variable_color));
219         
220 //      y += 20;
221 //      add_subwindow(new BC_Title(x, y, _("Next label:")));
222 //      add_subwindow(next_label_title = new BC_Title(x1, 
223 //              y, 
224 //              _("None"), 
225 //              MEDIUMFONT, 
226 //              mwindow->theme->recordgui_variable_color));
227 // 
228 // Curent batch
229         x = mwindow->theme->recordgui_batch_x;
230         y = mwindow->theme->recordgui_batch_y;
231         x1 = mwindow->theme->recordgui_batchcaption_x;
233         add_subwindow(batch_path_title = new BC_Title(x, y, _("Path:")));
234         add_subwindow(batch_path = new RecordPath(mwindow, record, x1, y));
235         add_subwindow(batch_browse = new BrowseButton(mwindow, 
236                 this, 
237                 batch_path, 
238                 batch_path->get_x() + batch_path->get_w(), 
239                 y,
240                 record->default_asset->path,
241                 PROGRAM_NAME ": Record path",
242                 _("Select a file to record to:"),
243                 0));
245         y += 30;
246         add_subwindow(batch_start_title = new BC_Title(x, y, _("Start time:")));
247         batch_start = new RecordStart(mwindow, record, x1, y);
248         batch_start->create_objects();
250         y += 30;
251         add_subwindow(batch_duration_title = new BC_Title(x, y, _("Duration time:")));
252         batch_duration = new RecordDuration(mwindow, record, x1, y);
253         batch_duration->create_objects();
255         y += 30;
256         add_subwindow(batch_source_title = new BC_Title(x, y, _("Source:")));
257         batch_source = new RecordSource(mwindow, record, this, x1, y);
258         batch_source->create_objects();
259         y += 30;
260         add_subwindow(batch_mode_title = new BC_Title(x, y, _("Mode:")));
261         batch_mode = new RecordMode(mwindow, record, this, x1, y);
262         batch_mode->create_objects();
263         y += 30;
265         add_subwindow(transport_title = 
266                 new BC_Title(mwindow->theme->recordgui_transport_x, 
267                         mwindow->theme->recordgui_transport_y, _("Transport:")));
268         record_transport = new RecordTransport(mwindow, 
269                 record, 
270                 this, 
271                 x1,
272                 mwindow->theme->recordgui_transport_y + 5);
273         record_transport->create_objects();
275         x = mwindow->theme->recordgui_buttons_x;
276         y = mwindow->theme->recordgui_buttons_y;
277         add_subwindow(new_batch = new RecordGUINewBatch(mwindow, record, x, y));
278         x += new_batch->get_w() + 5;
279         add_subwindow(delete_batch = new RecordGUIDeleteBatch(mwindow, record, x, y));
280         x += delete_batch->get_w() + 5;
281         add_subwindow(start_batches = new RecordGUIStartBatches(mwindow, record, x, y));
282         x += start_batches->get_w() + 5;
283         add_subwindow(activate_batch = new RecordGUIActivateBatch(mwindow, record, x, y));
284         x += activate_batch->get_w() + 5;
285         add_subwindow(label_button = new RecordGUILabel(mwindow, record, x, y));
287         x = mwindow->theme->recordgui_options_x;
288         y = mwindow->theme->recordgui_options_y;
290         if(record->default_asset->video_data) 
291         {
292                 add_subwindow(fill_frames = new RecordGUIFillFrames(mwindow, record, x, y));
293                 x += fill_frames->get_w() + 5;
294                 add_subwindow(monitor_video = new RecordGUIMonitorVideo(mwindow, record, x, y));
295                 x += monitor_video->get_w() + 5;
296         }
298         if(record->default_asset->audio_data) 
299                 add_subwindow(monitor_audio = new RecordGUIMonitorAudio(mwindow, record, x, y));
301 // Batches
302         add_subwindow(batch_list = new RecordGUIBatches(record, 
303                 this, 
304                 mwindow->theme->recordgui_batches_x, 
305                 mwindow->theme->recordgui_batches_y,
306                 mwindow->theme->recordgui_batches_w,
307                 mwindow->theme->recordgui_batches_h));
309 // Controls
310         load_mode = new LoadMode(mwindow,
311                 this, 
312                 mwindow->theme->recordgui_loadmode_x, 
313                 mwindow->theme->recordgui_loadmode_y, 
314                 &record->load_mode, 
315                 1);
316         load_mode->create_objects();
318         y = mwindow->theme->recordgui_controls_y;
319         x = mwindow->theme->recordgui_controls_x;
320         add_subwindow(save = new RecordGUISave(record, this, x, y));
322         x = get_w() - 90;
323         cancel_thread = new RecordCancelThread(record, this);
324         add_subwindow(cancel = new RecordGUICancel(record, this, x, y));
326         startover_thread = new RecordStartoverThread(record, this);
328 //printf("RecordGUI::create_objects 2\n");
329         return 0;
332 void RecordGUI::flash_batch()
334         if(record->current_batch < batches[0].total)
335         {
336                 if(flash_color == GREEN)
337                         flash_color = RED;
338                 else
339                         flash_color = GREEN;
341 //printf("RecordGUI::flash_batch %x\n", flash_color);
343                 for(int i = 0; i < BATCH_COLUMNS; i++)
344                 {
345                         BC_ListBoxItem *batch = batches[i].values[record->current_batch];
346                         batch->set_color(flash_color);
347                 }
348                 batch_list->update(batches,
349                         batch_titles,
350                         column_widths,
351                         BATCH_COLUMNS,
352                         batch_list->get_yposition(),
353                         batch_list->get_xposition(),
354                         batch_list->get_highlighted_item());
356                 batch_list->flush();
357         }
360 void RecordGUI::update_batches()
362         char string[BCTEXTLEN], string2[BCTEXTLEN];
363         FileSystem fs;
365         int selection_number = batch_list ? batch_list->get_selection_number(0, 0) : -1;
366         for(int j = 0; j < BATCH_COLUMNS; j++)
367         {
368                 batches[j].remove_all_objects();
369         }
371         for(int i = 0; i < record->batches.total; i++)
372         {
373                 Batch *batch = record->batches.values[i];
374                 int color = (i == record->current_batch) ? RED : BLACK;
375                 if(batch->waiting && time(0) & 0x1) color = GREEN;
377                 batches[0].append(new BC_ListBoxItem((char*)(batch->enabled ? "X" : " "), color));
378                 batches[1].append(new BC_ListBoxItem(batch->get_current_asset()->path, color));
379                 sprintf(string, "%s", batch->news);
380                 batches[2].append(new BC_ListBoxItem(string, RED));
381                 Units::totext(string2, 
382                                 batch->start_time, 
383                                 TIME_HMS, 
384                                 record->default_asset->sample_rate,
385                                 record->default_asset->frame_rate, 
386                                 mwindow->edl->session->frames_per_foot);
387                 sprintf(string, "%s %s", TimeEntry::day_table[batch->start_day], string2);
389                 batches[3].append(new BC_ListBoxItem(string, color));
390                 Units::totext(string, 
391                                 batch->duration, 
392                                 TIME_HMS, 
393                                 record->default_asset->sample_rate,
394                                 record->default_asset->frame_rate, 
395                                 mwindow->edl->session->frames_per_foot);
396                 batches[4].append(new BC_ListBoxItem(string, color));
397                 record->source_to_text(string, batch);
398                 batches[5].append(new BC_ListBoxItem(string, color));
399                 sprintf(string, "%s", Batch::mode_to_text(batch->record_mode));
400                 batches[6].append(new BC_ListBoxItem(string, color));
401                 
402                 if(i == selection_number)
403                 {
404                         for(int j = 0; j < BATCH_COLUMNS; j++)
405                         {
406                                 batches[j].values[i]->set_selected(1);
407                         }
408                 }
409         }
411         if(batch_list)
412         {
413                 batch_list->update(batches,
414                         batch_titles,
415                         column_widths,
416                         BATCH_COLUMNS,
417                         batch_list->get_yposition(),
418                         batch_list->get_xposition(),
419                         record->editing_batch,
420                         1);
421         }
422         flush();
425 void RecordGUI::update_batch_sources()
427 //printf("RecordGUI::update_batch_sources 1\n");
428         if(record->record_monitor->window->channel_picker)
429                 batch_source->update_list(
430                         &record->record_monitor->window->channel_picker->channel_listitems);
431 //printf("RecordGUI::update_batch_sources 2\n");
434 int RecordGUI::translation_event()
436         mwindow->session->rwindow_x = get_x();
437         mwindow->session->rwindow_y = get_y();
438         return 0;
442 int RecordGUI::resize_event(int w, int h)
444         int x, y, x1;
446         mwindow->session->rwindow_x = get_x();
447         mwindow->session->rwindow_y = get_y();
448         mwindow->session->rwindow_w = w;
449         mwindow->session->rwindow_h = h;
450         mwindow->theme->get_recordgui_sizes(this, w, h);
451         mwindow->theme->draw_rwindow_bg(this);
455         x = mwindow->theme->recordgui_batch_x;
456         y = mwindow->theme->recordgui_batch_y;
457         x1 = mwindow->theme->recordgui_batchcaption_x;
459         batch_path_title->reposition_window(x, y);
460         batch_path->reposition_window(x1, y);
461         batch_browse->reposition_window(batch_path->get_x() + batch_path->get_w(), 
462                 y);
463         y += 30;
464         batch_start_title->reposition_window(x, y);
465         batch_start->reposition_window(x1, y);
466         y += 30;
467         batch_duration_title->reposition_window(x, y);
468         batch_duration->reposition_window(x1, y);
469         y += 30;
470         batch_source_title->reposition_window(x, y);
471         batch_source->reposition_window(x1, y);
472         y += 30;
473         batch_mode_title->reposition_window(x, y);
474         batch_mode->reposition_window(x1, y);
475         
476         transport_title->reposition_window(mwindow->theme->recordgui_transport_x, 
477                 mwindow->theme->recordgui_transport_y);
478         record_transport->reposition_window(mwindow->theme->recordgui_batchcaption_x,
479                 mwindow->theme->recordgui_transport_y + 5);
480         
481         x = mwindow->theme->recordgui_buttons_x;
482         y = mwindow->theme->recordgui_buttons_y;
483         new_batch->reposition_window(x, y);
484         x += new_batch->get_w() + 5;
485         delete_batch->reposition_window(x, y);
486         x += delete_batch->get_w() + 5;
487         start_batches->reposition_window(x, y);
488         x += start_batches->get_w() + 5;
489         activate_batch->reposition_window(x, y);
490         x += activate_batch->get_w() + 5;
491         label_button->reposition_window(x, y);
494         batch_list->reposition_window(mwindow->theme->recordgui_batches_x, 
495                 mwindow->theme->recordgui_batches_y,
496                 mwindow->theme->recordgui_batches_w,
497                 mwindow->theme->recordgui_batches_h);
499         load_mode->reposition_window(mwindow->theme->recordgui_loadmode_x,
500                 mwindow->theme->recordgui_loadmode_y);
502         x = mwindow->theme->recordgui_controls_x;
503         y = mwindow->theme->recordgui_controls_y;
505         save->reposition_window(x, y);
507         x = w - 90;
508         cancel->reposition_window(x, y);
510         flash();
511         return 1;
514 void RecordGUI::update_batch_tools()
516 //printf("RecordGUI::update_batch_tools 1\n");
517         char string[BCTEXTLEN];
518         Batch *batch = record->get_editing_batch();
519         batch_path->update(batch->get_current_asset()->path);
521 // File is open in editing batch
522 //      if(record->current_batch == record->editing_batch && record->file)
523 //              batch_path->disable();
524 //      else
525 //              batch_path->enable();
527         batch_start->update(&batch->start_day, &batch->start_time);
528         batch_duration->update(0, &batch->duration);
529         batch_source->update(batch->get_source_text());
530         batch_mode->update(Batch::mode_to_text(batch->record_mode));
531         flush();
535 RecordGUIBatches::RecordGUIBatches(Record *record, RecordGUI *gui, int x, int y, int w, int h)
536  : BC_ListBox(x, 
537                 y, 
538                 w, 
539                 h,
540                 LISTBOX_TEXT,                   // Display text list or icons
541                 gui->batches,               // Each column has an ArrayList of BC_ListBoxItems.
542                 gui->batch_titles,             // Titles for columns.  Set to 0 for no titles
543                 gui->column_widths,                // width of each column
544                 BATCH_COLUMNS,                      // Total columns.
545                 0,                    // Pixel of top of window.
546                 0,                        // If this listbox is a popup window
547                 LISTBOX_SINGLE,  // Select one item or multiple items
548                 ICON_LEFT,        // Position of icon relative to text of each item
549                 1)           // Allow dragging
551         this->record = record;
552         this->gui = gui;
553         dragging_item = 0;
556 // Do nothing for double clicks to protect active batch
557 int RecordGUIBatches::handle_event()
559         return 1;
562 int RecordGUIBatches::selection_changed()
564         if(get_selection_number(0, 0) >= 0)
565         {
566                 int i = get_selection_number(0, 0);
567                 record->change_editing_batch(get_selection_number(0, 0));
568                 if(get_cursor_x() < gui->column_widths[0])
569                 {
570                         record->batches.values[i]->enabled = 
571                                 !record->batches.values[i]->enabled;
572                         gui->update_batches();
573                 }
574         }
575         return 1;
578 int RecordGUIBatches::column_resize_event()
580         for(int i = 0; i < BATCH_COLUMNS; i++)
581         {
582                 gui->column_widths[i] = get_column_width(i);
583         }
584         return 1;
587 int RecordGUIBatches::drag_start_event()
589         if(BC_ListBox::drag_start_event())
590         {
591                 dragging_item = 1;
592                 return 1;
593         }
595         return 0;
598 int RecordGUIBatches::drag_motion_event()
600         if(BC_ListBox::drag_motion_event())
601         {
602                 return 1;
603         }
604         return 0;
607 int RecordGUIBatches::drag_stop_event()
609         if(dragging_item)
610         {
611                 int src = record->editing_batch;
612                 int dst = get_highlighted_item();
613                 Batch *src_item = record->batches.values[src];
614                 if(dst < 0) dst = record->batches.total;
616                 for(int i = src; i < record->batches.total - 1; i++)
617                 {
618                         record->batches.values[i] = record->batches.values[i + 1];
619                 }
620                 if(dst > src) dst--;
621                 
622                 for(int i = record->batches.total - 1; i > dst; i--)
623                 {
624                         record->batches.values[i] = record->batches.values[i - 1];
625                 }
626                 record->batches.values[dst] = src_item;
628                 BC_ListBox::drag_stop_event();
630                 dragging_item = 0;
631                 gui->update_batches();
632         }
645 RecordGUISave::RecordGUISave(Record *record, RecordGUI *record_gui, int x, int y)
646  : BC_GenericButton(x, y, _("Close"))
648         set_tooltip(_("Save the recording and quit."));
649         this->record = record;
650         this->gui = record_gui;
653 int RecordGUISave::handle_event()
655         gui->set_done(0);
656         return 1;
659 int RecordGUISave::keypress_event()
661 //      if(get_keypress() == RETURN)
662 //      {
663 //              handle_event();
664 //              return 1;
665 //      }
667         return 0;
670 RecordGUICancel::RecordGUICancel(Record *record, RecordGUI *record_gui, int x, int y)
671  : BC_GenericButton(x, y, _("Cancel"))
673         set_tooltip(_("Quit without pasting into project."));
674         this->record = record;
675         this->gui = record_gui;
678 int RecordGUICancel::handle_event()
680         if(!gui->cancel_thread->running())
681                 gui->cancel_thread->start();
682         return 1;
685 int RecordGUICancel::keypress_event()
687         if(get_keypress() == ESC)
688         {
689                 handle_event();
690                 return 1;
691         }
693         return 0;
696 RecordGUIStartOver::RecordGUIStartOver(Record *record, RecordGUI *record_gui, int x, int y)
697  : BC_GenericButton(x, y, _("Start Over"))
699         set_tooltip(_("Rewind the current file and erase."));
700         this->record = record;
701         this->gui = record_gui;
703 RecordGUIStartOver::~RecordGUIStartOver()
707 int RecordGUIStartOver::handle_event()
709         if(!gui->startover_thread->running())
710                 gui->startover_thread->start();
711         return 1;
714 RecordGUIFillFrames::RecordGUIFillFrames(MWindow *mwindow, Record *record, int x, int y)
715  : BC_CheckBox(x, y, record->fill_frames, _("Fill frames"))
717         this->mwindow = mwindow;
718         this->record = record;
719         set_tooltip(_("Write extra frames when behind."));
722 int RecordGUIFillFrames::handle_event()
724 // Video capture constitutively, just like audio, but only flash on screen if 1
725         record->fill_frames = get_value();
726         return 1;
729 RecordGUIMonitorVideo::RecordGUIMonitorVideo(MWindow *mwindow, Record *record, int x, int y)
730  : BC_CheckBox(x, y, record->monitor_video, _("Monitor video"))
732         this->mwindow = mwindow;
733         this->record = record;
736 int RecordGUIMonitorVideo::handle_event()
738 // Video capture constitutively, just like audio, but only flash on screen if 1
739         record->monitor_video = get_value();
740         if(record->monitor_video)
741         {
742                 record->record_monitor->window->lock_window("RecordGUIMonitorVideo::handle_event");
743                 record->record_monitor->window->show_window();
744                 record->record_monitor->window->raise_window();
745                 record->record_monitor->window->flush();
746                 record->record_monitor->window->unlock_window();
747                 record->video_window_open = 1;
748         }
749         return 1;
753 RecordGUIMonitorAudio::RecordGUIMonitorAudio(MWindow *mwindow, Record *record, int x, int y)
754  : BC_CheckBox(x, y, record->monitor_audio, _("Monitor audio"))
756         this->mwindow = mwindow;
757         this->record = record;
760 int RecordGUIMonitorAudio::handle_event()
762         record->monitor_audio = get_value();
763         if(record->monitor_audio)
764         {
765                 record->record_monitor->window->lock_window("RecordGUIMonitorAudio::handle_event");
766                 record->record_monitor->window->show_window();
767                 record->record_monitor->window->raise_window();
768                 record->record_monitor->window->flush();
769                 record->record_monitor->window->unlock_window();
770                 record->video_window_open = 1;
771         }
772         return 1;
775 RecordBatch::RecordBatch(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
776  : BC_PopupTextBox(gui, 
777                 &gui->batch_numbers,
778                 gui->batch_numbers.values[record->editing_batch]->get_text(),
779                 x, 
780                 y, 
781                 100,
782                 200)
784         this->gui = gui;
785         this->mwindow = mwindow;
786         this->record = record;
788 int RecordBatch::handle_event()
790         return 1;
793 RecordPath::RecordPath(MWindow *mwindow, Record *record, int x, int y)
794  : BC_TextBox(x, y, 200, 1, record->get_editing_batch()->get_current_asset()->path)
796         this->mwindow = mwindow;
797         this->record = record;
799 int RecordPath::handle_event()
801         strcpy(record->get_editing_batch()->assets.values[0]->path, get_text());
802         record->get_editing_batch()->calculate_news();
803         record->record_gui->update_batches();
804         return 1;
807 RecordStartType::RecordStartType(MWindow *mwindow, Record *record, int x, int y)
808  : BC_CheckBox(x, y, record->get_editing_batch()->start_type, _("Offset"))
810         this->mwindow = mwindow;
811         this->record = record;
813 int RecordStartType::handle_event()
815         return 1;
819 RecordStart::RecordStart(MWindow *mwindow, Record *record, int x, int y)
820  : TimeEntry(record->record_gui, 
821                 x, 
822                 y, 
823                 &(record->get_editing_batch()->start_day), 
824                 &(record->get_editing_batch()->start_time),
825                 TIME_HMS3)
827         this->mwindow = mwindow;
828         this->record = record;
830 int RecordStart::handle_event()
832         record->record_gui->update_batches();
833         return 1;
836 RecordDuration::RecordDuration(MWindow *mwindow, Record *record, int x, int y)
837  : TimeEntry(record->record_gui, 
838                 x, 
839                 y, 
840                 0, 
841                 &(record->get_editing_batch()->duration),
842                 TIME_HMS2)
844         this->mwindow = mwindow;
845         this->record = record;
847 int RecordDuration::handle_event()
849         record->record_gui->update_batches();
850         return 1;
853 RecordSource::RecordSource(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
854  : BC_PopupTextBox(gui, 
855         &gui->sources,
856         record->get_editing_batch()->get_source_text(),
857         x, 
858         y, 
859         200,
860         200)
862         this->mwindow = mwindow;
863         this->record = record;
864         this->gui = gui;
866 int RecordSource::handle_event()
868         record->set_channel(get_number());
869         return 1;
872 RecordMode::RecordMode(MWindow *mwindow, Record *record, RecordGUI *gui, int x, int y)
873  : BC_PopupTextBox(gui,
874         &gui->modes,
875         Batch::mode_to_text(record->get_editing_batch()->record_mode),
876         x,
877         y,
878         200,
879         100)
881         this->mwindow = mwindow;
882         this->record = record;
884 int RecordMode::handle_event()
886         record->get_editing_batch()->record_mode = Batch::text_to_mode(get_text());
887         record->record_gui->update_batches();
888         return 1;
891 RecordNews::RecordNews(MWindow *mwindow, Record *record, int x, int y)
892  : BC_TextBox(x, y, 200, 1, record->get_editing_batch()->news)
894         this->mwindow = mwindow;
895         this->record = record;
897 int RecordNews::handle_event()
899         return 1;
903 RecordGUINewBatch::RecordGUINewBatch(MWindow *mwindow, Record *record, int x, int y)
904  : BC_GenericButton(x, y, _("New"))
906         this->mwindow = mwindow;
907         this->record = record;
908         set_tooltip(_("Create new clip."));
910 int RecordGUINewBatch::handle_event()
912         record->new_batch();
913         record->record_gui->update_batches();
914         return 1;
918 RecordGUIDeleteBatch::RecordGUIDeleteBatch(MWindow *mwindow, Record *record, int x, int y)
919  : BC_GenericButton(x, y, _("Delete"))
921         this->mwindow = mwindow;
922         this->record = record;
923         set_tooltip(_("Delete clip."));
925 int RecordGUIDeleteBatch::handle_event()
927         record->delete_batch();
928         record->record_gui->update_batches();
929         return 1;
933 RecordGUIStartBatches::RecordGUIStartBatches(MWindow *mwindow, Record *record, int x, int y)
934  : BC_GenericButton(x, y, _("Start"))
936         this->mwindow = mwindow;
937         this->record = record;
938         set_tooltip(_("Start batch recording\nfrom the current position."));
940 int RecordGUIStartBatches::handle_event()
942         unlock_window();
943         record->start_recording(0, CONTEXT_BATCH);
944         lock_window("RecordGUIStartBatches::handle_event");
945         return 1;
949 RecordGUIStopbatches::RecordGUIStopbatches(MWindow *mwindow, Record *record, int x, int y)
950  : BC_GenericButton(x, y, _("Stop"))
952         this->mwindow = mwindow;
953         this->record = record;
955 int RecordGUIStopbatches::handle_event()
957         return 1;
961 RecordGUIActivateBatch::RecordGUIActivateBatch(MWindow *mwindow, Record *record, int x, int y)
962  : BC_GenericButton(x, y, _("Activate"))
964         this->mwindow = mwindow;
965         this->record = record;
966         set_tooltip(_("Make the highlighted\nclip active."));
968 int RecordGUIActivateBatch::handle_event()
970         record->activate_batch(record->editing_batch, 1);
971         return 1;
975 RecordGUILabel::RecordGUILabel(MWindow *mwindow, Record *record, int x, int y)
976  : BC_GenericButton(x, y, _("Label"))
978         this->mwindow = mwindow;
979         this->record = record;
980         set_underline(0);
984 RecordGUILabel::~RecordGUILabel()
988 int RecordGUILabel::handle_event()
990         record->toggle_label();
991         return 1;
994 int RecordGUILabel::keypress_event()
996         if(get_keypress() == 'l')
997         {
998                 handle_event();
999                 return 1;
1000         }
1001         return 0;
1020 RecordCancelThread::RecordCancelThread(Record *record, RecordGUI *record_gui)
1021  : Thread(1, 0, 0)
1023         this->record = record;
1024         this->gui = record_gui;
1027 RecordCancelThread::~RecordCancelThread()
1029         if(Thread::running()) 
1030         {
1031                 window->lock_window("RecordCancelThread::~RecordCancelThread");
1032                 window->set_done(1);
1033                 window->unlock_window();
1034                 Thread::join();
1035         }
1039 void RecordCancelThread::run()
1041         if(record->prompt_cancel)
1042         {
1043                 window = new QuestionWindow(record->mwindow);
1044                 window->create_objects(_("Quit without pasting into project?"), 0);
1045                 int result = window->run_window();
1046                 if(result == 2) gui->set_done(1);
1047                 delete window;
1048         }
1049         else
1050         {
1051                 gui->set_done(1);
1052         }
1056 RecordStartoverThread::RecordStartoverThread(Record *record, RecordGUI *record_gui)
1057  : Thread(1, 0, 0)
1059         this->record = record;
1060         this->gui = record_gui;
1062 RecordStartoverThread::~RecordStartoverThread()
1064         if(Thread::running()) 
1065         {
1066                 window->lock_window("RecordStartoverThread::~RecordStartoverThread");
1067                 window->set_done(1);
1068                 window->unlock_window();
1069                 Thread::join();
1070         }
1073 void RecordStartoverThread::run()
1075         window = new QuestionWindow(record->mwindow);
1076         window->create_objects(_("Rewind batch and overwrite?"), 0);
1077         int result = window->run_window();
1078         if(result == 2) record->start_over();
1079         delete window;
1115 int RecordGUI::set_translation(int x, int y, float z)
1117         record->video_x = x;
1118         record->video_y = y;
1119         record->video_zoom = z;
1122 int RecordGUI::update_dropped_frames(long new_dropped)
1124         status_thread->update_dropped_frames(new_dropped);
1125         return 0;
1128 int RecordGUI::update_position(double new_position) 
1130         status_thread->update_position(new_position);
1131         return 0;
1134 int RecordGUI::update_clipped_samples(long new_clipped)
1136         status_thread->update_clipped_samples(new_clipped);
1137         return 0;
1140 int RecordGUI::keypress_event()
1142         return record_transport->keypress_event();
1145 void RecordGUI::update_labels(double new_position)
1147         RecordLabel *prev, *next;
1148         char string[BCTEXTLEN];
1150         for(prev = record->get_current_batch()->labels->last; 
1151                 prev; 
1152                 prev = prev->previous)
1153         {
1154                 if(prev->position <= new_position) break;
1155         }
1157         for(next = record->get_current_batch()->labels->first; 
1158                 next; 
1159                 next = next->next)
1160         {
1161                 if(next->position > new_position) break;
1162         }
1164         if(prev)
1165                 update_title(prev_label_title, 
1166                         prev->position);
1167         else
1168                 update_title(prev_label_title, -1);
1170 //      if(next)
1171 //              update_title(next_label_title, (double)next->position / record->default_asset->sample_rate);
1172 //      else
1173 //              update_title(next_label_title, -1);
1178 int RecordGUI::update_prev_label(long new_position) 
1180         update_title(prev_label_title, new_position);
1183 // int RecordGUI::update_next_label(long new_position) 
1184 // { 
1185 //      update_title(next_label_title, new_position); 
1186 // }
1187 // 
1188 int RecordGUI::update_title(BC_Title *title, double position)
1190         static char string[256];
1192         if(position > -1)
1193         {
1194                 Units::totext(string, 
1195                                 position, 
1196                                 mwindow->edl->session->time_format, 
1197                                 record->default_asset->sample_rate, 
1198                                 record->default_asset->frame_rate, 
1199                                 mwindow->edl->session->frames_per_foot);
1200         }
1201         else
1202         {
1203                 sprintf(string, "-");
1204         }
1205         lock_window("RecordGUI::update_title");
1206         title->update(string);
1207         unlock_window();
1210 int RecordGUI::update_duration_boxes()
1212         char string[1024];
1213 //      sprintf(string, "%d", engine->get_loop_hr());
1214 //      loop_hr->update(string);
1215 //      sprintf(string, "%d", engine->get_loop_min());
1216 //      loop_min->update(string);
1217 //      sprintf(string, "%d", engine->get_loop_sec());
1218 //      loop_sec->update(string);
1226 // ===================================== GUI
1232 // ================================================== modes
1234 RecordGUIModeMenu::RecordGUIModeMenu(int x, 
1235         int y, 
1236         int w, 
1237         char *text)
1238  : BC_PopupMenu(x, y, w, text)
1242 RecordGUIModeMenu::~RecordGUIModeMenu()
1244         delete linear;
1245         delete timed;
1246         delete loop;
1249 int RecordGUIModeMenu::add_items()
1251         add_item(linear = new RecordGUIMode(_("Untimed")));
1252         add_item(timed = new RecordGUIMode(_("Timed")));
1253 //      add_item(loop = new RecordGUIMode("_(Loop")));
1254         return 0;
1257 int RecordGUIModeMenu::handle_event()
1259 //      engine->set_record_mode(get_text());
1262 RecordGUIMode::RecordGUIMode(char *text)
1263  : BC_MenuItem(text)
1267 RecordGUIMode::~RecordGUIMode()
1271 int RecordGUIMode::handle_event()
1273         get_popup_menu()->set_text(get_text());
1274         get_popup_menu()->handle_event();
1275         return 1;
1282 RecordStatusThread::RecordStatusThread(MWindow *mwindow, RecordGUI *gui)
1283  : Thread(1, 0, 0)
1285         this->mwindow = mwindow;
1286         this->gui = gui;
1287         new_dropped_frames = -1;
1288         new_position = -1;
1289         new_clipped_samples = -1;
1290         input_lock = new Condition(0, "RecordStatusThread::input_lock");
1291         done = 0;
1294 RecordStatusThread::~RecordStatusThread()
1296         if(Thread::running())
1297         {
1298                 done = 1;
1299                 input_lock->unlock();
1300                 Thread::join();
1301         }
1304 void RecordStatusThread::update_dropped_frames(long value)
1306         new_dropped_frames = value;
1307         input_lock->unlock();
1310 void RecordStatusThread::update_position(double new_position)
1312         this->new_position = new_position;
1313         input_lock->unlock();
1316 void RecordStatusThread::update_clipped_samples(long new_clipped_samples)
1318         this->new_clipped_samples = new_clipped_samples;
1319         input_lock->unlock();
1322 void RecordStatusThread::run()
1324         while(!done)
1325         {
1326                 input_lock->lock("RecordStatusThread::run");
1327                 if(new_dropped_frames >= 0)
1328                 {
1329                         char string[1024];
1330                         if(gui->total_dropped_frames != new_dropped_frames)
1331                         {
1332                                 gui->total_dropped_frames = new_dropped_frames;
1333                                 sprintf(string, "%d\n", gui->total_dropped_frames);
1334                                 gui->lock_window("RecordStatusThread::run 1");
1335                                 gui->frames_dropped->update(string);
1336                                 gui->unlock_window();
1337                         }
1338                 }
1339                 
1340                 if(new_position >= 0)
1341                 {
1342                         gui->update_title(gui->position_title, new_position);
1343                         gui->update_labels(new_position);
1344                 }
1345                 
1346                 if(new_clipped_samples >= 0)
1347                 {
1348                         if(gui->total_clipped_samples != new_clipped_samples)
1349                         {
1350                                 char string[1024];
1351                                 gui->total_clipped_samples = new_clipped_samples;
1352                                 sprintf(string, "%d\n", gui->total_clipped_samples);
1353                                 gui->lock_window("RecordStatusThread::run 2");
1354                                 gui->samples_clipped->update(string);
1355                                 gui->unlock_window();
1356                         }
1357                 }
1359                 new_clipped_samples = -1;
1360                 new_dropped_frames = -1;
1361                 new_position = -1;
1362         }
1372 RecordGUIDCOffset::RecordGUIDCOffset(MWindow *mwindow, int y)
1373  : BC_Button(230, y, mwindow->theme->calibrate_data)
1377 RecordGUIDCOffset::~RecordGUIDCOffset() {}
1379 int RecordGUIDCOffset::handle_event()
1381 //      engine->calibrate_dc_offset();
1382         return 1;
1385 int RecordGUIDCOffset::keypress_event() { return 0; }
1387 RecordGUIDCOffsetText::RecordGUIDCOffsetText(char *text, int y, int number)
1388  : BC_TextBox(30, y+1, 67, 1, text, 0)
1390         this->number = number; 
1393 RecordGUIDCOffsetText::~RecordGUIDCOffsetText()
1396         
1397 int RecordGUIDCOffsetText::handle_event()
1399 //      if(!engine->is_previewing)
1400 //      {
1401 //              engine->calibrate_dc_offset(atol(get_text()), number);
1402 //      }
1403         return 1;
1406 RecordGUIReset::RecordGUIReset(MWindow *mwindow, RecordGUI *gui, int y)
1407  : BC_Button(400, y, mwindow->theme->over_button)
1408 { this->gui = gui; }
1410 RecordGUIReset::~RecordGUIReset() 
1414 int RecordGUIReset::handle_event()
1416 //      for(int i = 0; i < gui->engine->get_input_channels(); i++)
1417 //      {
1418 //              gui->meter[i]->reset_over();
1419 //      }
1420         return 1;
1423 RecordGUIResetTranslation::RecordGUIResetTranslation(MWindow *mwindow, RecordGUI *gui, int y)
1424  : BC_Button(250, y, mwindow->theme->reset_data)
1425 { this->gui = gui; }
1427 RecordGUIResetTranslation::~RecordGUIResetTranslation() 
1431 int RecordGUIResetTranslation::handle_event()
1433         gui->set_translation(0, 0, 1);
1434         return 1;
1441 RecordGUIOK::RecordGUIOK(MWindow *mwindow, int y)
1442  : BC_OKButton(50, y)
1446 RecordGUIOK::~RecordGUIOK()
1450 int RecordGUIOK::handle_event()
1452         unlock_window();
1453 //      engine->set_done(0);
1454         lock_window();
1455         return 1;