4 * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "bcsignals.h"
25 #include "browsebutton.h"
27 #include "channelpicker.h"
29 #include "condition.h"
32 #include "edlsession.h"
34 #include "filesystem.h"
38 #include "meterpanel.h"
41 #include "mwindowgui.h"
42 #include "preferences.h"
44 #include "recconfirmdelete.h"
45 #include "recordgui.h"
47 #include "recordlabel.h"
48 #include "recordmonitor.h"
49 #include "recordtransport.h"
50 #include "recordvideo.h"
51 #include "mainsession.h"
54 #include "videodevice.h"
61 RecordGUI::RecordGUI(MWindow *mwindow, Record *record)
62 : BC_Window(_(PROGRAM_NAME ": Recording"),
63 mwindow->session->rwindow_x, mwindow->session->rwindow_y,
64 mwindow->session->rwindow_w, mwindow->session->rwindow_h,
65 xS(10), yS(10), 1, 0, 1)
67 this->mwindow = mwindow;
68 this->record = record;
70 current_operation = 0;
100 interrupt_thread = 0;
107 monitor_video_window = 0;
108 dc_offset_button = 0;
109 for( int i=0; i<MAXCHANNELS; ++i ) {
110 dc_offset_text[i] = 0;
113 total_dropped_frames = 0;
114 total_clipped_samples = 0;
117 RecordGUI::~RecordGUI()
119 delete status_thread;
120 delete record_transport;
124 delete startover_thread;
125 delete interrupt_thread;
127 delete batch_duration;
132 void RecordGUI::create_objects()
134 int xs5 = xS(5), xs10 = xS(10), xs20 = xS(20), xs30 = xS(30);
135 int ys5 = yS(5), ys10 = yS(10);
136 char string[BCTEXTLEN];
138 Asset *asset = record->default_asset;
139 lock_window("RecordGUI::create_objects");
140 status_thread = new RecordStatusThread(mwindow, this);
141 status_thread->start();
142 set_icon(mwindow->theme->get_image("record_icon"));
144 mwindow->theme->get_recordgui_sizes(this, get_w(), get_h());
145 //printf("RecordGUI::create_objects 1\n");
146 mwindow->theme->draw_rwindow_bg(this);
152 int pad = max(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1),
153 BC_Title::calculate_h(this, "X")) + ys5;
157 add_subwindow(title = new BC_Title(x, y, _("Path:")));
158 x1 = max(title->get_w(), x1);
160 add_subwindow(title = new BC_Title(x, y, _("Start time:")));
161 x1 = max(title->get_w(), x1);
163 add_subwindow(title = new BC_Title(x, y, _("Duration time:")));
164 x1 = max(title->get_w(), x1);
166 add_subwindow(title = new BC_Title(x, y, _("Source:")));
167 x1 = max(title->get_w(), x1);
169 add_subwindow(title = new BC_Title(x, y, _("Mode:")));
170 x1 = max(title->get_w(), x1);
172 add_subwindow(title = new BC_Title(x, y, _("Transport:")));
173 x1 = max(title->get_w(), x1);
176 button_y = max(y, button_y);
183 add_subwindow(batch_path = new RecordPath(this, x, y));
184 add_subwindow(batch_browse = new BrowseButton(mwindow->theme,
187 batch_path->get_x() + batch_path->get_w(),
190 _(PROGRAM_NAME ": Record path"),
191 _("Select a file to record to:"),
193 x2 = max(x2, batch_path->get_w() + batch_browse->get_w());
195 batch_start = new RecordStart(this, x, y);
196 batch_start->create_objects();
197 x2 = max(x2, batch_start->get_w());
199 batch_duration = new RecordDuration(this, x, y);
200 batch_duration->create_objects();
201 x2 = max(x2, batch_duration->get_w());
203 batch_source = new RecordSource(this, x, y);
204 batch_source->create_objects();
205 x2 = max(x2, batch_source->get_w());
207 batch_mode = new RecordGUIModeMenu(this, x, y, xS(200), "");
208 batch_mode->create_objects();
209 x2 = max(x2, batch_mode->get_w());
211 record_transport = new RecordTransport(mwindow,
213 record_transport->create_objects();
214 x2 = max(x2, record_transport->get_w());
219 // Compression settings
223 pad = BC_Title::calculate_h(this, "X") + ys5;
224 add_subwindow(title = new BC_Title(x, y, _("Format:")));
225 x3 = max(title->get_w(), x3);
228 if(asset->audio_data)
230 add_subwindow(title = new BC_Title(x, y, _("Audio compression:")));
231 x3 = max(title->get_w(), x3);
233 add_subwindow(title = new BC_Title(x, y, _("Samplerate:")));
234 x3 = max(title->get_w(), x3);
236 add_subwindow(title = new BC_Title(x, y, _("Clipped samples:")));
237 x3 = max(title->get_w(), x3);
241 if(asset->video_data)
243 add_subwindow(title = new BC_Title(x, y, _("Video compression:")));
244 x3 = max(title->get_w(), x3);
246 add_subwindow(title = new BC_Title(x, y, _("Framerate:")));
247 x3 = max(title->get_w(), x3);
249 add_subwindow(title = new BC_Title(x, y, _("Frames dropped:")));
250 x3 = max(title->get_w(), x3);
252 add_subwindow(title = new BC_Title(x, y, _("Frames behind:")));
253 x3 = max(title->get_w(), x3);
257 add_subwindow(title = new BC_Title(x, y, _("Position:")));
258 x3 = max(title->get_w(), x3);
260 add_subwindow(title = new BC_Title(x, y, _("Prev label:")));
261 x3 = max(title->get_w(), x3);
264 button_y = max(y, button_y);
266 x = x3 + x2 + x1 + xS(40);
268 add_subwindow(new BC_Title(x, y,
269 File::formattostr(asset->format),
271 mwindow->theme->recordgui_fixed_color));
274 if(asset->audio_data) {
275 add_subwindow(new BC_Title(x, y,
276 File::bitstostr(asset->bits),
278 mwindow->theme->recordgui_fixed_color));
281 sprintf(string, "%d", asset->sample_rate);
282 add_subwindow(new BC_Title(x, y,
284 mwindow->theme->recordgui_fixed_color));
287 add_subwindow(samples_clipped = new BC_Title(x, y,
289 mwindow->theme->recordgui_variable_color));
293 if(asset->video_data) {
294 add_subwindow(new BC_Title(x, y,
295 asset->format == FILE_MPEG ? _("File Capture") :
296 File::compressiontostr(asset->vcodec),
298 mwindow->theme->recordgui_fixed_color));
301 sprintf(string, "%0.2f", asset->frame_rate);
302 add_subwindow(framerate = new BC_Title(x, y,
304 mwindow->theme->recordgui_fixed_color));
307 add_subwindow(frames_dropped = new BC_Title(x, y,
309 mwindow->theme->recordgui_variable_color));
311 add_subwindow(frames_behind = new BC_Title(x, y,
313 mwindow->theme->recordgui_variable_color));
317 add_subwindow(position_title = new BC_Title(x, y,
319 mwindow->theme->recordgui_variable_color));
322 add_subwindow(prev_label_title = new BC_Title(x, y,
323 _("None"), MEDIUMFONT,
324 mwindow->theme->recordgui_variable_color));
327 button_y = max(y, button_y);
333 add_subwindow(title = new BC_Title(x,y, _("Batches:")));
334 int y_max = y + title->get_h(); x1 = x;
335 x += title->get_w() + xs5;
336 add_subwindow(activate_batch = new RecordGUIActivateBatch(this, x, y));
337 x += activate_batch->get_w();
338 y_max = max(y_max, y + activate_batch->get_h());
339 add_subwindow(start_batches = new RecordGUIStartBatches(this, x, y));
340 y_max = max(y_max, y + start_batches->get_h()); x2 = x;
341 x += start_batches->get_w();
342 add_subwindow(new_batch = new RecordGUINewBatch(this, x, y));
343 y_max = max(y_max, y + new_batch->get_h()); x3 = x;
344 x += new_batch->get_w(); int x4 = x;
345 add_subwindow(label_button = new RecordGUILabel(this, x, y));
346 y_max = max(y_max, y + label_button->get_h());
348 int y1 = y_max, y2 = y1 + ys5;
349 add_subwindow(title = new BC_Title(x1,y2, _("Cron:")));
350 y_max = max(y_max, y2 + title->get_h());
351 x1 += title->get_w() + xs5;
352 add_subwindow(cron_status = new BC_Title(x1,y2, _("Idle"), MEDIUMFONT,
353 mwindow->theme->recordgui_variable_color));
354 y_max = max(y_max, y2 + cron_status->get_h());
355 add_subwindow(stop_batches = new RecordGUIStopBatches(this, x2, y1));
356 y_max = max(y_max, y1 + stop_batches->get_h());
357 add_subwindow(delete_batch = new RecordGUIDeleteBatch(this, x3, y1));
358 y_max = max(y_max, y1 + delete_batch->get_h());
359 add_subwindow(clrlbls_button = new RecordGUIClearLabels(this, x4, y1));
360 y_max = max(y_max, y1 + clrlbls_button->get_h());
370 if(asset->video_data) {
371 add_subwindow(drop_frames = new RecordGUIDropFrames(this, x, y));
372 add_subwindow(fill_frames = new RecordGUIFillFrames(this, x, y1));
373 x += drop_frames->get_w() + xs5; x1 = x;
374 add_subwindow(monitor_video = new RecordGUIMonitorVideo(this, x, y));
375 x += monitor_video->get_w() + xs5;
378 if(asset->audio_data) {
379 add_subwindow(monitor_audio = new RecordGUIMonitorAudio(this, x, y));
380 x += monitor_audio->get_w() + xs5;
381 add_subwindow(meter_audio = new RecordGUIAudioMeters(this, x, y));
382 x += meter_audio->get_w() + xs5;
385 add_subwindow(power_off = new RecordGUIPowerOff(this, x1, y1));
386 x1 += power_off->get_w() + xs10;
387 add_subwindow(commercial_check = new RecordGUICommCheck(this, x1, y1));
393 y = y1 + fill_frames->get_h();
394 else if( monitor_audio )
395 y += monitor_audio->get_h();
397 int bottom_margin = max(BC_OKButton::calculate_h(),
398 LoadMode::calculate_h(this, mwindow->theme)) + ys5;
401 add_subwindow(batch_bay = new RecordGUIBatches(this, x, y,
402 get_w() - xs20, get_h() - y - bottom_margin - ys10));
403 y += batch_bay->get_h() + ys5;
404 record->record_batches.gui = batch_bay;
405 batch_bay->update_batches(-1);
408 int loadmode_w = LoadMode::calculate_w(this, mwindow->theme);
409 load_mode = new LoadMode(mwindow, this,
410 get_w() / 2 - loadmode_w / 2, y, &record->load_mode);
411 load_mode->create_objects();
412 y += load_mode->get_h() + ys5;
414 add_subwindow(new RecordGUIOK(this));
416 interrupt_thread = new EndRecordThread(this);
417 // add_subwindow(new RecordGUISave(record, this));
418 add_subwindow(new RecordGUICancel(this));
420 startover_thread = new RecordStartoverThread(this);
422 enable_batch_buttons();
423 if( batch_mode->value == RECORD_TIMED )
424 batch_duration->enable();
426 batch_duration->disable();
430 void RecordGUI::update_batches()
432 lock_window("void RecordGUI::Update_batches");
433 batch_bay->update_batches();
438 Batch *RecordGUI::get_current_batch()
440 return record->get_editing_batch();
443 Batch *RecordGUI::get_editing_batch()
445 return record->get_editing_batch();
448 void RecordGUI::update_batch_sources()
450 //printf("RecordGUI::update_batch_sources 1\n");
451 ChannelPicker *channel_picker =
452 record->record_monitor->window->channel_picker;
454 batch_source->update_list(&channel_picker->channel_listitems);
455 //printf("RecordGUI::update_batch_sources 2\n");
458 int RecordGUI::translation_event()
460 mwindow->session->rwindow_x = get_x();
461 mwindow->session->rwindow_y = get_y();
466 int RecordGUI::resize_event(int w, int h)
468 int xs20 = xS(20), ys10 = yS(10);
469 // Recompute batch list based on previous extents
470 int bottom_margin = mwindow->session->rwindow_h -
473 int mode_margin = mwindow->session->rwindow_h - load_mode->get_y();
474 mwindow->session->rwindow_x = get_x();
475 mwindow->session->rwindow_y = get_y();
476 mwindow->session->rwindow_w = w;
477 mwindow->session->rwindow_h = h;
478 mwindow->theme->get_recordgui_sizes(this, w, h);
479 mwindow->theme->draw_rwindow_bg(this);
481 int new_h = mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y();
482 if(new_h < ys10) new_h = ys10;
483 batch_bay->reposition_window(batch_bay->get_x(),
485 mwindow->session->rwindow_w - xs20,
486 mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y());
488 load_mode->reposition_window(mwindow->session->rwindow_w / 2 -
489 mwindow->theme->loadmode_w / 2,
490 mwindow->session->rwindow_h - mode_margin);
496 void RecordGUI::update_batch_tools()
498 lock_window("RecordGUI::update_batch_tools");
499 //printf("RecordGUI::update_batch_tools 1\n");
500 Batch *batch = get_editing_batch();
501 batch_path->update(batch->asset->path);
503 // File is open in editing batch
504 // if(current_batch() == editing_batch() && record->file)
505 // batch_path->disable();
507 // batch_path->enable();
509 batch_start->update(&batch->start_day, &batch->start_time);
510 batch_duration->update(0, &batch->duration);
511 batch_source->update(batch->get_source_text());
512 batch_mode->update(batch->record_mode);
513 if( batch_mode->value == RECORD_TIMED )
514 batch_duration->enable();
516 batch_duration->disable();
521 void RecordGUI::enable_batch_buttons()
523 lock_window("RecordGUI::enable_batch_buttons");
525 delete_batch->enable();
526 start_batches->enable();
527 stop_batches->disable();
528 activate_batch->enable();
532 void RecordGUI::disable_batch_buttons()
534 lock_window("RecordGUI::disable_batch_buttons");
535 new_batch->disable();
536 delete_batch->disable();
537 start_batches->disable();
538 stop_batches->enable();
539 activate_batch->disable();
543 RecordGUIBatches::RecordGUIBatches(RecordGUI *gui, int x, int y, int w, int h)
544 : RecordBatchesGUI(gui->record->record_batches, x, y, w, h)
549 // Do nothing for double clicks to protect active batch
550 int RecordGUIBatches::handle_event()
555 int RecordGUIBatches::selection_changed()
557 RecordBatchesGUI::selection_changed();
558 gui->update_batch_tools();
563 RecordGUISave::RecordGUISave(RecordGUI *gui)
565 gui->get_h() - BC_WindowBase::get_resources()->ok_images[0]->get_h() - yS(10),
566 BC_WindowBase::get_resources()->ok_images)
568 set_tooltip(_("Save the recording and quit."));
572 int RecordGUISave::handle_event()
578 int RecordGUISave::keypress_event()
580 // if(get_keypress() == RETURN)
588 RecordGUICancel::RecordGUICancel(RecordGUI *gui)
589 : BC_CancelButton(gui)
591 set_tooltip(_("Quit without pasting into project."));
595 int RecordGUICancel::handle_event()
597 gui->interrupt_thread->start(0);
601 int RecordGUICancel::keypress_event()
603 if(get_keypress() == ESC)
613 RecordGUIOK::RecordGUIOK(RecordGUI *gui)
616 set_tooltip(_("Quit and paste into project."));
620 int RecordGUIOK::handle_event()
622 gui->interrupt_thread->start(1);
627 RecordGUIStartOver::RecordGUIStartOver(RecordGUI *gui, int x, int y)
628 : BC_GenericButton(x, y, _("Start Over"))
630 set_tooltip(_("Rewind the current file and erase."));
633 RecordGUIStartOver::~RecordGUIStartOver()
637 int RecordGUIStartOver::handle_event()
639 if(!gui->startover_thread->running())
640 gui->startover_thread->start();
645 RecordGUIDropFrames::RecordGUIDropFrames(RecordGUI *gui, int x, int y)
646 : BC_CheckBox(x, y, gui->record->drop_overrun_frames, _("drop overrun frames"))
648 this->set_underline(0);
650 set_tooltip(_("Drop input frames when behind."));
653 int RecordGUIDropFrames::handle_event()
655 gui->record->drop_overrun_frames = get_value();
659 int RecordGUIDropFrames::keypress_event()
661 if( get_keypress() == caption[0] ) {
662 set_value(get_value() ? 0 : 1);
669 RecordGUIFillFrames::RecordGUIFillFrames(RecordGUI *gui, int x, int y)
670 : BC_CheckBox(x, y, gui->record->fill_underrun_frames, _("fill underrun frames"))
672 this->set_underline(0);
674 set_tooltip(_("Write extra frames when behind."));
677 int RecordGUIFillFrames::handle_event()
679 gui->record->fill_underrun_frames = get_value();
683 int RecordGUIFillFrames::keypress_event()
685 if( get_keypress() == caption[0] ) {
686 set_value(get_value() ? 0 : 1);
693 RecordGUIPowerOff::RecordGUIPowerOff(RecordGUI *gui, int x, int y)
694 : BC_CheckBox(x, y, gui->record->power_off, _("poweroff when done"))
696 this->set_underline(0);
698 set_tooltip(_("poweroff system when batch record done."));
701 int RecordGUIPowerOff::handle_event()
703 gui->record->power_off = get_value();
707 int RecordGUIPowerOff::keypress_event()
709 if( get_keypress() == caption[0] ) {
710 set_value(get_value() ? 0 : 1);
718 RecordGUICommCheck::RecordGUICommCheck(RecordGUI *gui, int x, int y)
719 : BC_CheckBox(x, y, gui->record->commercial_check, _("check for ads"))
721 this->set_underline(0);
723 set_tooltip(_("check for commercials."));
726 int RecordGUICommCheck::handle_event()
728 gui->record->update_skimming(get_value());
733 int RecordGUICommCheck::keypress_event()
735 if( get_keypress() == caption[0] ) {
736 set_value(get_value() ? 0 : 1);
737 gui->record->update_skimming(get_value());
745 RecordGUIMonitorVideo::RecordGUIMonitorVideo(RecordGUI *gui, int x, int y)
746 : BC_CheckBox(x, y, gui->record->monitor_video, _("Monitor video"))
748 this->set_underline(8);
752 int RecordGUIMonitorVideo::handle_event()
754 // Video capture constitutively, just like audio, but only flash on screen if 1
755 int mode = get_value();
756 Record *record = gui->record;
757 record->set_video_monitoring(mode);
758 if(record->monitor_video) {
760 BC_Window *window = record->record_monitor->window;
761 window->lock_window("RecordGUIMonitorVideo::handle_event");
762 window->show_window();
763 window->raise_window();
765 window->unlock_window();
766 lock_window("RecordGUIMonitorVideo::handle_event");
767 record->video_window_open = 1;
773 int RecordGUIMonitorVideo::keypress_event()
775 if(get_keypress() == 'v') {
776 set_value(get_value() ? 0 : 1);
785 RecordGUIMonitorAudio::RecordGUIMonitorAudio(RecordGUI *gui, int x, int y)
786 : BC_CheckBox(x, y, gui->record->monitor_audio, _("Monitor audio"))
788 this->set_underline(8);
792 int RecordGUIMonitorAudio::handle_event()
794 int mode = get_value();
795 Record *record = gui->record;
796 record->set_audio_monitoring(mode);
797 if(record->monitor_audio) {
799 BC_Window *window = record->record_monitor->window;
800 window->lock_window("RecordGUIMonitorAudio::handle_event");
801 window->show_window();
802 window->raise_window();
804 window->unlock_window();
805 lock_window("RecordGUIMonitorAudio::handle_event");
806 record->video_window_open = 1;
811 int RecordGUIMonitorAudio::keypress_event()
813 if(get_keypress() == 'a') {
814 set_value(get_value() ? 0 : 1);
822 RecordGUIAudioMeters::RecordGUIAudioMeters(RecordGUI *gui, int x, int y)
823 : BC_CheckBox(x, y, gui->record->metering_audio, _("Audio meters"))
825 this->set_underline(6);
829 int RecordGUIAudioMeters::handle_event()
831 int mode = get_value();
832 Record *record = gui->record;
833 record->set_audio_metering(mode);
834 if(record->metering_audio) {
836 BC_Window *window = record->record_monitor->window;
837 window->lock_window("RecordGUIAudioMeters::handle_event");
838 window->show_window();
839 window->raise_window();
841 window->unlock_window();
842 lock_window("RecordGUIAudioMeters::handle_event");
843 record->video_window_open = 1;
848 int RecordGUIAudioMeters::keypress_event()
850 if(get_keypress() == 'm') {
851 set_value(get_value() ? 0 : 1);
858 RecordPath::RecordPath(RecordGUI *gui, int x, int y)
859 : RecordBatchesGUI::Path(gui->record->record_batches, x, y)
864 int RecordPath::handle_event()
866 return RecordBatchesGUI::Path::handle_event();
870 RecordStart::RecordStart(RecordGUI *gui, int x, int y)
871 : RecordBatchesGUI::StartTime(gui, gui->record->record_batches, x, y)
876 int RecordStart::handle_event()
878 return RecordBatchesGUI::StartTime::handle_event();
881 RecordDuration::RecordDuration(RecordGUI *gui, int x, int y)
882 : RecordBatchesGUI::Duration(gui, gui->record->record_batches, x, y)
887 int RecordDuration::handle_event()
889 return RecordBatchesGUI::Duration::handle_event();
893 RecordSource::RecordSource(RecordGUI *gui, int x, int y)
894 : RecordBatchesGUI::Source(gui, gui->record->record_batches, x, y)
899 int RecordSource::handle_event()
901 gui->record->set_batch_channel_no(get_number());
902 return RecordBatchesGUI::Source::handle_event();
906 RecordNews::RecordNews(RecordGUI *gui, int x, int y)
907 : RecordBatchesGUI::News(gui->record->record_batches, x, y)
912 int RecordNews::handle_event()
914 return RecordBatchesGUI::News::handle_event();
918 RecordGUINewBatch::RecordGUINewBatch(RecordGUI *gui, int x, int y)
919 : RecordBatchesGUI::NewBatch(gui->record->record_batches, x, y)
922 set_tooltip(_("Create new clip."));
924 int RecordGUINewBatch::handle_event()
926 gui->record->new_batch();
927 return RecordBatchesGUI::NewBatch::handle_event();
931 RecordGUIDeleteBatch::RecordGUIDeleteBatch(RecordGUI *gui, int x, int y)
932 : RecordBatchesGUI::DeleteBatch(gui->record->record_batches, x, y)
935 set_tooltip(_("Delete clip."));
938 int RecordGUIDeleteBatch::handle_event()
940 gui->record->delete_batch();
941 return RecordBatchesGUI::DeleteBatch::handle_event();
945 RecordGUIStartBatches::RecordGUIStartBatches(RecordGUI *gui, int x, int y)
946 : RecordBatchesGUI::StartBatches(gui->record->record_batches, x, y)
949 set_tooltip(_("Start batch recording\nfrom the current position."));
952 int RecordGUIStartBatches::handle_event()
954 Record *record = gui->record;
955 record->start_cron_thread();
956 return RecordBatchesGUI::StartBatches::handle_event();
960 RecordGUIStopBatches::RecordGUIStopBatches(RecordGUI *gui, int x, int y)
961 : RecordBatchesGUI::StopBatches(gui->record->record_batches, x, y)
966 int RecordGUIStopBatches::handle_event()
968 Record *record = gui->record;
970 record->stop_cron_thread(_("Stopped"));
972 return RecordBatchesGUI::StopBatches::handle_event();
976 RecordGUIActivateBatch::RecordGUIActivateBatch(RecordGUI *gui, int x, int y)
977 : RecordBatchesGUI::ActivateBatch(gui->record->record_batches, x, y)
980 set_tooltip(_("Make the highlighted\nclip active."));
982 int RecordGUIActivateBatch::handle_event()
984 gui->record->activate_batch(gui->record->editing_batch());
985 gui->update_cron_status(_("Idle"));
986 return RecordBatchesGUI::ActivateBatch::handle_event();
990 RecordGUILabel::RecordGUILabel(RecordGUI *gui, int x, int y)
991 : BC_GenericButton(x, y, _("Label"))
998 RecordGUILabel::~RecordGUILabel()
1002 int RecordGUILabel::handle_event()
1004 gui->record->toggle_label();
1008 int RecordGUILabel::keypress_event()
1010 if( get_keypress() == *get_text() ) {
1018 RecordGUIClearLabels::RecordGUIClearLabels(RecordGUI *gui, int x, int y)
1019 : BC_GenericButton(x, y, _("ClrLbls"))
1025 RecordGUIClearLabels::~RecordGUIClearLabels()
1029 int RecordGUIClearLabels::handle_event()
1031 gui->record->clear_labels();
1036 EndRecordThread::EndRecordThread(RecordGUI *gui)
1043 EndRecordThread::~EndRecordThread()
1045 if(Thread::running()) {
1046 window->lock_window("EndRecordThread::~EndRecordThread");
1047 window->set_done(1);
1048 window->unlock_window();
1053 void EndRecordThread::start(int is_ok)
1055 this->is_ok = is_ok;
1056 if( gui->record->writing_file ) {
1061 gui->set_done(!is_ok);
1065 void EndRecordThread::run()
1067 window = new QuestionWindow(gui->record->mwindow);
1068 window->create_objects(_("Interrupt recording in progress?"), 0);
1069 int result = window->run_window();
1071 if(result == 2) gui->set_done(!is_ok);
1075 RecordStartoverThread::RecordStartoverThread(RecordGUI *gui)
1080 RecordStartoverThread::~RecordStartoverThread()
1082 if(Thread::running()) {
1083 window->lock_window("RecordStartoverThread::~RecordStartoverThread");
1084 window->set_done(1);
1085 window->unlock_window();
1090 void RecordStartoverThread::run()
1092 Record *record = gui->record;
1093 window = new QuestionWindow(record->mwindow);
1094 window->create_objects(_("Rewind batch and overwrite?"), 0);
1095 int result = window->run_window();
1096 if(result == 2) record->start_over();
1101 int RecordGUI::set_translation(int x, int y, float z)
1103 record->video_x = x;
1104 record->video_y = y;
1105 record->video_zoom = z;
1109 void RecordGUI::reset_video()
1111 total_dropped_frames = 0;
1112 status_thread->reset_video();
1113 update_framerate(record->default_asset->frame_rate);
1116 void RecordGUI::update_dropped_frames(long value)
1118 status_thread->update_dropped_frames(value);
1121 void RecordGUI::update_frames_behind(long value)
1123 status_thread->update_frames_behind(value);
1126 void RecordGUI::update_position(double value)
1128 status_thread->update_position(value);
1131 void RecordGUI::update_framerate(double value)
1133 status_thread->update_framerate(value);
1136 void RecordGUI::update_video(int dropped, int behind)
1138 total_dropped_frames += dropped;
1139 update_dropped_frames(total_dropped_frames);
1140 update_frames_behind(behind);
1141 status_thread->update_position(record->current_display_position());
1144 void RecordGUI::reset_audio()
1146 // gui->lock_window("RecordAudio::run 2");
1148 total_clipped_samples = 0;
1149 status_thread->reset_audio();
1150 AudioDevice *adevice = record->adevice;
1151 RecordMonitorGUI *window = record->record_monitor->window;
1152 window->lock_window("RecordAudio::run 2");
1153 MeterPanel *meters = window->meters;
1155 int dmix = adevice && (adevice->get_idmix() || adevice->get_odmix());
1156 meters->init_meters(dmix);
1158 window->unlock_window();
1159 // gui->unlock_window();
1162 void RecordGUI::update_clipped_samples(long value)
1164 status_thread->update_clipped_samples(value);
1167 void RecordGUI::update_audio(int channels, double *max, int *over)
1169 // Get clipping status
1171 for( int ch=0; ch<channels && !clipped; ++ch )
1172 if( over[ch] ) clipped = 1;
1174 update_clipped_samples(++total_clipped_samples);
1176 // Update meters if monitoring
1177 if( record->metering_audio ) {
1178 RecordMonitorGUI *window = record->record_monitor->window;
1179 window->lock_window("RecordAudio::run 1");
1180 MeterPanel *meters = window->meters;
1181 int nmeters = meters->meters.total;
1182 for( int ch=0; ch<nmeters; ++ch ) {
1183 double vmax = ch < channels ? max[ch] : 0.;
1184 int vover = ch < channels ? over[ch] : 0;
1185 meters->meters.values[ch]->update(vmax, vover);
1187 window->unlock_window();
1189 // update position, if no video
1190 if( !record->default_asset->video_data )
1191 update_position(record->current_display_position());
1195 int RecordGUI::keypress_event()
1197 return record_transport->keypress_event();
1200 void RecordGUI::update_labels(double new_position)
1202 RecordLabel *prev, *next;
1204 for(prev = record->get_current_batch()->labels->last;
1206 prev = prev->previous) {
1207 if(prev->position <= new_position) break;
1210 for(next = record->get_current_batch()->labels->first;
1214 if(next->position > new_position) break;
1218 update_title(prev_label_title, prev->position);
1220 update_title(prev_label_title, -1);
1223 // update_title(next_label_title, (double)next->position / record->default_asset->sample_rate);
1225 // update_title(next_label_title, -1);
1229 int RecordGUI::update_prev_label(long new_position)
1231 update_title(prev_label_title, new_position);
1235 // int RecordGUI::update_next_label(long new_position)
1237 // update_title(next_label_title, new_position);
1240 int RecordGUI::update_title(BC_Title *title, double position)
1242 static char string[256];
1245 Units::totext(string,
1247 mwindow->edl->session->time_format,
1248 record->default_asset->sample_rate,
1249 record->default_asset->frame_rate,
1250 mwindow->edl->session->frames_per_foot);
1253 sprintf(string, "-");
1255 title->update(string);
1260 void RecordGUI::update_cron_status(const char *status)
1262 lock_window("RecordGUI::update_cron_status");
1263 cron_status->update(status);
1267 void RecordGUI::update_power_off(int value)
1269 lock_window("RecordGUI::update_power_off");
1270 power_off->update(value);
1277 // ===================================== GUI
1278 // ================================================== modes
1280 RecordGUIModeTextBox::RecordGUIModeTextBox(RecordGUIModeMenu *mode_menu,
1281 int x, int y, int w,const char *text)
1282 : BC_TextBox(x, y, w, 1, text)
1284 this->mode_menu = mode_menu;
1287 RecordGUIModeTextBox::~RecordGUIModeTextBox()
1291 int RecordGUIModeTextBox::handle_event()
1296 RecordGUIModeListBox::RecordGUIModeListBox(RecordGUIModeMenu *mode_menu)
1297 : BC_ListBox(mode_menu->textbox->get_x() + mode_menu->textbox->get_w(),
1298 mode_menu->textbox->get_y(), xS(100), yS(50), LISTBOX_TEXT,
1299 &mode_menu->modes, 0, 0, 1, 0, 1)
1301 this->mode_menu = mode_menu;
1304 RecordGUIModeListBox::~RecordGUIModeListBox()
1308 int RecordGUIModeListBox::handle_event()
1310 return mode_menu->handle_event();
1313 RecordGUIModeMenu::RecordGUIModeMenu(RecordGUI *record_gui,
1314 int x, int y, int w,const char *text)
1316 this->record_gui = record_gui;
1317 textbox = new RecordGUIModeTextBox(this,x, y, w, "");
1318 record_gui->add_subwindow(textbox);
1319 listbox = new RecordGUIModeListBox(this);
1320 record_gui->add_subwindow(listbox);
1323 RecordGUIModeMenu::~RecordGUIModeMenu()
1325 for( int i=0; i<modes.total; ++i )
1326 delete modes.values[i];
1331 void RecordGUIModeMenu::create_objects()
1333 value = RECORD_UNTIMED;
1334 modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_UNTIMED)));
1335 modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_TIMED)));
1336 textbox->update(modes.values[value]->get_text());
1339 int RecordGUIModeMenu::handle_event()
1341 value = listbox->get_selection_number(0, 0);
1342 textbox->update(modes.values[value]->get_text());
1343 textbox->handle_event();
1344 record_gui->record->set_record_mode(value);
1345 if( value == RECORD_TIMED )
1346 record_gui->batch_duration->enable();
1348 record_gui->batch_duration->disable();
1352 void RecordGUIModeMenu::update(int value)
1354 this->value = value;
1355 textbox->update(modes.values[value]->get_text());
1358 int RecordGUIModeMenu::get_w()
1360 return textbox->get_w() + listbox->get_w();
1363 int RecordGUIModeMenu::get_h()
1365 return MAX(textbox->get_h(), listbox->get_h());
1369 RecordStatusThread::RecordStatusThread(MWindow *mwindow, RecordGUI *gui)
1372 this->mwindow = mwindow;
1374 input_lock = new Condition(0, "RecordStatusThread::input_lock");
1381 RecordStatusThread::~RecordStatusThread()
1383 if(Thread::running())
1386 input_lock->unlock();
1392 void RecordStatusThread::reset_video()
1394 new_dropped_frames = 0;
1395 displayed_dropped_frames = -1;
1396 new_frames_behind = 0;
1397 displayed_frames_behind = -1;
1399 displayed_framerate = -1.;
1403 void RecordStatusThread::reset_audio()
1405 new_clipped_samples = 0;
1406 displayed_clipped_samples = -1;
1409 void RecordStatusThread::update_frames_behind(long value)
1411 if( value != displayed_frames_behind ) {
1412 new_frames_behind = value;
1413 input_lock->unlock();
1417 void RecordStatusThread::update_dropped_frames(long value)
1419 if( value != displayed_dropped_frames ) {
1420 new_dropped_frames = value;
1421 input_lock->unlock();
1425 void RecordStatusThread::update_clipped_samples(long value)
1427 if( value != displayed_clipped_samples ) {
1428 new_clipped_samples = value;
1429 input_lock->unlock();
1433 void RecordStatusThread::update_position(double value)
1435 this->new_position = value;
1436 input_lock->unlock();
1439 void RecordStatusThread::update_framerate(double value)
1441 if( value != displayed_framerate ) {
1442 new_framerate = value;
1443 input_lock->unlock();
1447 void RecordStatusThread::get_window_lock()
1449 if( !window_locked ) {
1450 gui->lock_window("RecordStatusThread::run 1");
1456 void RecordStatusThread::
1457 update_status_string(const char *fmt, T &new_value, T &displayed_value, BC_Title *widgit)
1459 if( new_value >= 0 ) {
1460 if( displayed_value != new_value ) {
1461 displayed_value = new_value;
1464 sprintf(string, fmt, displayed_value);
1466 widgit->update(string);
1473 void RecordStatusThread::run()
1476 input_lock->lock("RecordStatusThread::run");
1478 update_status_string("%d", new_dropped_frames, displayed_dropped_frames,
1479 gui->frames_dropped);
1480 update_status_string("%d", new_frames_behind, displayed_frames_behind,
1481 gui->frames_behind);
1482 update_status_string("%d", new_clipped_samples, displayed_clipped_samples,
1483 gui->samples_clipped);
1484 update_status_string("%0.2f", new_framerate, displayed_framerate,
1486 if( new_position >= 0 ) {
1488 gui->update_title(gui->position_title, new_position);
1489 gui->update_labels(new_position);
1492 if( window_locked ) {
1493 gui->unlock_window();
1500 void RecordGUI::start_flash_batch()
1502 if( batch_flash ) return;
1503 batch_flash = new RecordGUIFlash(this);
1506 void RecordGUI::stop_flash_batch()
1508 if( !batch_flash ) return;
1513 void RecordGUI::flash_batch()
1515 lock_window("void RecordGUI::flash_batch");
1516 int cur_batch = record->current_batch();
1517 if( cur_batch >= 0 && cur_batch < batch_bay->count()) {
1518 flash_color = flash_color == GREEN ? RED : GREEN;
1519 //printf("RecordGUI::flash_batch %x\n", flash_color);
1520 batch_bay->set_row_color(cur_batch, flash_color);
1521 batch_bay->update_batch_news(cur_batch);
1527 RecordGUIFlash(RecordGUI *record_gui)
1530 this->record_gui = record_gui;
1531 flash_lock = new Condition(0,"RecordGUIFlash::flash_lock");
1539 if( Thread::running() ) {
1541 flash_lock->unlock();
1548 void RecordGUIFlash::run()
1551 record_gui->flash_batch();
1560 RecordGUIDCOffset::RecordGUIDCOffset(MWindow *mwindow, int y)
1561 : BC_Button(xS(230), y, mwindow->theme->calibrate_data)
1565 RecordGUIDCOffset::~RecordGUIDCOffset() {}
1567 int RecordGUIDCOffset::handle_event()
1572 int RecordGUIDCOffset::keypress_event() { return 0; }
1574 RecordGUIDCOffsetText::RecordGUIDCOffsetText(char *text, int y, int number)
1575 : BC_TextBox(xS(30), y+yS(1), xS(67), 1, text, 0)
1577 this->number = number;
1580 RecordGUIDCOffsetText::~RecordGUIDCOffsetText()
1584 int RecordGUIDCOffsetText::handle_event()
1589 RecordGUIReset::RecordGUIReset(MWindow *mwindow, RecordGUI *gui, int y)
1590 : BC_Button(xS(400), y, mwindow->theme->over_button)
1591 { this->gui = gui; }
1593 RecordGUIReset::~RecordGUIReset()
1597 int RecordGUIReset::handle_event()
1602 RecordGUIResetTranslation::RecordGUIResetTranslation(MWindow *mwindow, RecordGUI *gui, int y)
1603 : BC_Button(xS(250), y, mwindow->theme->reset_data)
1608 RecordGUIResetTranslation::~RecordGUIResetTranslation()
1612 int RecordGUIResetTranslation::handle_event()
1614 gui->set_translation(0, 0, 1);