4 * Copyright (C) 2008 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"
35 #include "filesystem.h"
39 #include "meterpanel.h"
42 #include "mwindowgui.h"
43 #include "preferences.h"
45 #include "recconfirmdelete.h"
46 #include "recordgui.h"
48 #include "recordlabel.h"
49 #include "recordmonitor.h"
50 #include "recordtransport.h"
51 #include "recordvideo.h"
52 #include "mainsession.h"
55 #include "videodevice.h"
62 RecordGUI::RecordGUI(MWindow *mwindow, Record *record)
63 : BC_Window(PROGRAM_NAME ": Recording",
64 mwindow->session->rwindow_x, mwindow->session->rwindow_y,
65 mwindow->session->rwindow_w, mwindow->session->rwindow_h,
68 this->mwindow = mwindow;
69 this->record = record;
71 current_operation = 0;
100 startover_thread = 0;
101 interrupt_thread = 0;
108 monitor_video_window = 0;
109 dc_offset_button = 0;
110 for( int i=0; i<MAXCHANNELS; ++i ) {
111 dc_offset_text[i] = 0;
114 total_dropped_frames = 0;
115 total_clipped_samples = 0;
118 RecordGUI::~RecordGUI()
120 TRACE("RecordGUI::~RecordGUI 1");
121 delete status_thread;
125 delete startover_thread;
126 delete interrupt_thread;
128 delete batch_duration;
130 TRACE("RecordGUI::~RecordGUI 2");
134 void RecordGUI::create_objects()
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")) + 5;
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,
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, 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") + 5;
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 + 40;
268 add_subwindow(new BC_Title(x, y,
269 File::formattostr(mwindow->plugindb, 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 ?
296 FileMOV::compressiontostr(asset->vcodec) :
299 mwindow->theme->recordgui_fixed_color));
302 sprintf(string, "%0.2f", asset->frame_rate);
303 add_subwindow(framerate = new BC_Title(x, y,
305 mwindow->theme->recordgui_fixed_color));
308 add_subwindow(frames_dropped = new BC_Title(x, y,
310 mwindow->theme->recordgui_variable_color));
312 add_subwindow(frames_behind = new BC_Title(x, y,
314 mwindow->theme->recordgui_variable_color));
318 add_subwindow(position_title = new BC_Title(x, y,
320 mwindow->theme->recordgui_variable_color));
323 add_subwindow(prev_label_title = new BC_Title(x, y,
324 _("None"), MEDIUMFONT,
325 mwindow->theme->recordgui_variable_color));
328 button_y = max(y, button_y);
334 add_subwindow(title = new BC_Title(x,y, _("Batches:")));
335 int y_max = y + title->get_h(); x1 = x;
336 x += title->get_w() + 5;
337 add_subwindow(activate_batch = new RecordGUIActivateBatch(this, x, y));
338 x += activate_batch->get_w();
339 y_max = max(y_max, y + activate_batch->get_h());
340 add_subwindow(start_batches = new RecordGUIStartBatches(this, x, y));
341 y_max = max(y_max, y + start_batches->get_h()); x2 = x;
342 x += start_batches->get_w();
343 add_subwindow(new_batch = new RecordGUINewBatch(this, x, y));
344 y_max = max(y_max, y + new_batch->get_h()); x3 = x;
345 x += new_batch->get_w(); int x4 = x;
346 add_subwindow(label_button = new RecordGUILabel(this, x, y));
347 y_max = max(y_max, y + label_button->get_h());
349 int y1 = y_max, y2 = y1 + 5;
350 add_subwindow(title = new BC_Title(x1,y2, _("Cron:")));
351 y_max = max(y_max, y2 + title->get_h());
352 x1 += title->get_w() + 5;
353 add_subwindow(cron_status = new BC_Title(x1,y2, _("Idle"), MEDIUMFONT,
354 mwindow->theme->recordgui_variable_color));
355 y_max = max(y_max, y2 + cron_status->get_h());
356 add_subwindow(stop_batches = new RecordGUIStopBatches(this, x2, y1));
357 y_max = max(y_max, y1 + stop_batches->get_h());
358 add_subwindow(delete_batch = new RecordGUIDeleteBatch(this, x3, y1));
359 y_max = max(y_max, y1 + delete_batch->get_h());
360 add_subwindow(clrlbls_button = new RecordGUIClearLabels(this, x4, y1));
361 y_max = max(y_max, y1 + clrlbls_button->get_h());
371 if(asset->video_data) {
372 add_subwindow(drop_frames = new RecordGUIDropFrames(this, x, y));
373 add_subwindow(fill_frames = new RecordGUIFillFrames(this, x, y1));
374 x += drop_frames->get_w() + 5; x1 = x;
375 add_subwindow(monitor_video = new RecordGUIMonitorVideo(this, x, y));
376 x += monitor_video->get_w() + 5;
379 if(asset->audio_data) {
380 add_subwindow(monitor_audio = new RecordGUIMonitorAudio(this, x, y));
381 x += monitor_audio->get_w() + 5;
382 add_subwindow(meter_audio = new RecordGUIAudioMeters(this, x, y));
383 x += meter_audio->get_w() + 5;
386 add_subwindow(power_off = new RecordGUIPowerOff(this, x1, y1));
387 x1 += power_off->get_w() + 10;
388 add_subwindow(commercial_check = new RecordGUICommCheck(this, x1, y1));
394 y = y1 + fill_frames->get_h();
395 else if( monitor_audio )
396 y += monitor_audio->get_h();
398 int bottom_margin = max(BC_OKButton::calculate_h(),
399 LoadMode::calculate_h(this, mwindow->theme)) + 5;
402 add_subwindow(batch_bay = new RecordGUIBatches(this, x, y,
403 get_w() - 20, get_h() - y - bottom_margin - 10));
404 y += batch_bay->get_h() + 5;
405 record->record_batches.gui = batch_bay;
406 batch_bay->update_batches(-1);
409 int loadmode_w = LoadMode::calculate_w(this, mwindow->theme, 1, 0);
410 load_mode = new LoadMode(mwindow, this,
411 get_w() / 2 - loadmode_w / 2, y,
412 &record->load_mode, 1, 0);
413 load_mode->create_objects();
414 y += load_mode->get_h() + 5;
416 add_subwindow(new RecordGUIOK(this));
418 interrupt_thread = new EndRecordThread(this);
419 // add_subwindow(new RecordGUISave(record, this));
420 add_subwindow(new RecordGUICancel(this));
422 startover_thread = new RecordStartoverThread(this);
424 enable_batch_buttons();
425 if( batch_mode->value == RECORD_TIMED )
426 batch_duration->enable();
428 batch_duration->disable();
432 void RecordGUI::update_batches()
434 lock_window("void RecordGUI::Update_batches");
435 batch_bay->update_batches();
440 Batch *RecordGUI::get_current_batch()
442 return record->get_editing_batch();
445 Batch *RecordGUI::get_editing_batch()
447 return record->get_editing_batch();
450 void RecordGUI::update_batch_sources()
452 //printf("RecordGUI::update_batch_sources 1\n");
453 ChannelPicker *channel_picker =
454 record->record_monitor->window->channel_picker;
456 batch_source->update_list(&channel_picker->channel_listitems);
457 //printf("RecordGUI::update_batch_sources 2\n");
460 int RecordGUI::translation_event()
462 mwindow->session->rwindow_x = get_x();
463 mwindow->session->rwindow_y = get_y();
468 int RecordGUI::resize_event(int w, int h)
470 // Recompute batch list based on previous extents
471 int bottom_margin = mwindow->session->rwindow_h -
474 int mode_margin = mwindow->session->rwindow_h - load_mode->get_y();
475 mwindow->session->rwindow_x = get_x();
476 mwindow->session->rwindow_y = get_y();
477 mwindow->session->rwindow_w = w;
478 mwindow->session->rwindow_h = h;
479 mwindow->theme->get_recordgui_sizes(this, w, h);
480 mwindow->theme->draw_rwindow_bg(this);
482 int new_h = mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y();
483 if(new_h < 10) new_h = 10;
484 batch_bay->reposition_window(batch_bay->get_x(),
486 mwindow->session->rwindow_w - 20,
487 mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y());
489 load_mode->reposition_window(mwindow->session->rwindow_w / 2 -
490 mwindow->theme->loadmode_w / 2,
491 mwindow->session->rwindow_h - mode_margin);
497 void RecordGUI::update_batch_tools()
499 lock_window("RecordGUI::update_batch_tools");
500 //printf("RecordGUI::update_batch_tools 1\n");
501 Batch *batch = get_editing_batch();
502 batch_path->update(batch->asset->path);
504 // File is open in editing batch
505 // if(current_batch() == editing_batch() && record->file)
506 // batch_path->disable();
508 // batch_path->enable();
510 batch_start->update(&batch->start_day, &batch->start_time);
511 batch_duration->update(0, &batch->duration);
512 batch_source->update(batch->get_source_text());
513 batch_mode->update(batch->record_mode);
514 if( batch_mode->value == RECORD_TIMED )
515 batch_duration->enable();
517 batch_duration->disable();
522 void RecordGUI::enable_batch_buttons()
524 lock_window("RecordGUI::enable_batch_buttons");
526 delete_batch->enable();
527 start_batches->enable();
528 stop_batches->disable();
529 activate_batch->enable();
533 void RecordGUI::disable_batch_buttons()
535 lock_window("RecordGUI::disable_batch_buttons");
536 new_batch->disable();
537 delete_batch->disable();
538 start_batches->disable();
539 stop_batches->enable();
540 activate_batch->disable();
544 RecordGUIBatches::RecordGUIBatches(RecordGUI *gui, int x, int y, int w, int h)
545 : RecordBatchesGUI(gui->record->record_batches, x, y, w, h)
550 // Do nothing for double clicks to protect active batch
551 int RecordGUIBatches::handle_event()
556 int RecordGUIBatches::selection_changed()
558 RecordBatchesGUI::selection_changed();
559 gui->update_batch_tools();
564 RecordGUISave::RecordGUISave(RecordGUI *gui)
566 gui->get_h() - BC_WindowBase::get_resources()->ok_images[0]->get_h() - 10,
567 BC_WindowBase::get_resources()->ok_images)
569 set_tooltip(_("Save the recording and quit."));
573 int RecordGUISave::handle_event()
579 int RecordGUISave::keypress_event()
581 // if(get_keypress() == RETURN)
589 RecordGUICancel::RecordGUICancel(RecordGUI *gui)
590 : BC_CancelButton(gui)
592 set_tooltip(_("Quit without pasting into project."));
596 int RecordGUICancel::handle_event()
598 gui->interrupt_thread->start(0);
602 int RecordGUICancel::keypress_event()
604 if(get_keypress() == ESC)
614 RecordGUIOK::RecordGUIOK(RecordGUI *gui)
617 set_tooltip(_("Quit and paste into project."));
621 int RecordGUIOK::handle_event()
623 gui->interrupt_thread->start(1);
628 RecordGUIStartOver::RecordGUIStartOver(RecordGUI *gui, int x, int y)
629 : BC_GenericButton(x, y, _("Start Over"))
631 set_tooltip(_("Rewind the current file and erase."));
634 RecordGUIStartOver::~RecordGUIStartOver()
638 int RecordGUIStartOver::handle_event()
640 if(!gui->startover_thread->running())
641 gui->startover_thread->start();
646 RecordGUIDropFrames::RecordGUIDropFrames(RecordGUI *gui, int x, int y)
647 : BC_CheckBox(x, y, gui->record->drop_overrun_frames, _("drop overrun frames"))
649 this->set_underline(0);
651 set_tooltip(_("Drop input frames when behind."));
654 int RecordGUIDropFrames::handle_event()
656 gui->record->drop_overrun_frames = get_value();
660 int RecordGUIDropFrames::keypress_event()
662 if(get_keypress() == 'd') {
663 set_value(get_value() ? 0 : 1);
670 RecordGUIFillFrames::RecordGUIFillFrames(RecordGUI *gui, int x, int y)
671 : BC_CheckBox(x, y, gui->record->fill_underrun_frames, _("fill underrun frames"))
673 this->set_underline(0);
675 set_tooltip(_("Write extra frames when behind."));
678 int RecordGUIFillFrames::handle_event()
680 gui->record->fill_underrun_frames = get_value();
684 int RecordGUIFillFrames::keypress_event()
686 if(get_keypress() == 'f') {
687 set_value(get_value() ? 0 : 1);
694 RecordGUIPowerOff::RecordGUIPowerOff(RecordGUI *gui, int x, int y)
695 : BC_CheckBox(x, y, gui->record->power_off, _("poweroff when done"))
697 this->set_underline(0);
699 set_tooltip(_("poweroff system when batch record done."));
702 int RecordGUIPowerOff::handle_event()
704 gui->record->power_off = get_value();
708 int RecordGUIPowerOff::keypress_event()
710 if(get_keypress() == 'p') {
711 set_value(get_value() ? 0 : 1);
719 RecordGUICommCheck::RecordGUICommCheck(RecordGUI *gui, int x, int y)
720 : BC_CheckBox(x, y, gui->record->commercial_check, _("check for ads"))
722 this->set_underline(0);
724 set_tooltip(_("check for commercials."));
727 int RecordGUICommCheck::handle_event()
729 gui->record->update_skimming(get_value());
734 int RecordGUICommCheck::keypress_event()
736 if(get_keypress() == 'c') {
737 set_value(get_value() ? 0 : 1);
738 gui->record->update_skimming(get_value());
746 RecordGUIMonitorVideo::RecordGUIMonitorVideo(RecordGUI *gui, int x, int y)
747 : BC_CheckBox(x, y, gui->record->monitor_video, _("Monitor video"))
749 this->set_underline(8);
753 int RecordGUIMonitorVideo::handle_event()
755 // Video capture constitutively, just like audio, but only flash on screen if 1
756 int mode = get_value();
757 Record *record = gui->record;
758 record->set_video_monitoring(mode);
759 if(record->monitor_video) {
761 BC_Window *window = record->record_monitor->window;
762 window->lock_window("RecordGUIMonitorVideo::handle_event");
763 window->show_window();
764 window->raise_window();
766 window->unlock_window();
767 lock_window("RecordGUIMonitorVideo::handle_event");
768 record->video_window_open = 1;
774 int RecordGUIMonitorVideo::keypress_event()
776 if(get_keypress() == 'v') {
777 set_value(get_value() ? 0 : 1);
786 RecordGUIMonitorAudio::RecordGUIMonitorAudio(RecordGUI *gui, int x, int y)
787 : BC_CheckBox(x, y, gui->record->monitor_audio, _("Monitor audio"))
789 this->set_underline(8);
793 int RecordGUIMonitorAudio::handle_event()
795 int mode = get_value();
796 Record *record = gui->record;
797 record->set_audio_monitoring(mode);
798 if(record->monitor_audio) {
800 BC_Window *window = record->record_monitor->window;
801 window->lock_window("RecordGUIMonitorAudio::handle_event");
802 window->show_window();
803 window->raise_window();
805 window->unlock_window();
806 lock_window("RecordGUIMonitorAudio::handle_event");
807 record->video_window_open = 1;
812 int RecordGUIMonitorAudio::keypress_event()
814 if(get_keypress() == 'a') {
815 set_value(get_value() ? 0 : 1);
823 RecordGUIAudioMeters::RecordGUIAudioMeters(RecordGUI *gui, int x, int y)
824 : BC_CheckBox(x, y, gui->record->metering_audio, _("Audio meters"))
826 this->set_underline(6);
830 int RecordGUIAudioMeters::handle_event()
832 int mode = get_value();
833 Record *record = gui->record;
834 record->set_audio_metering(mode);
835 if(record->metering_audio) {
837 BC_Window *window = record->record_monitor->window;
838 window->lock_window("RecordGUIAudioMeters::handle_event");
839 window->show_window();
840 window->raise_window();
842 window->unlock_window();
843 lock_window("RecordGUIAudioMeters::handle_event");
844 record->video_window_open = 1;
849 int RecordGUIAudioMeters::keypress_event()
851 if(get_keypress() == 'm') {
852 set_value(get_value() ? 0 : 1);
859 RecordPath::RecordPath(RecordGUI *gui, int x, int y)
860 : RecordBatchesGUI::Path(gui->record->record_batches, x, y)
865 int RecordPath::handle_event()
867 return RecordBatchesGUI::Path::handle_event();
871 RecordStart::RecordStart(RecordGUI *gui, int x, int y)
872 : RecordBatchesGUI::StartTime(gui, gui->record->record_batches, x, y)
877 int RecordStart::handle_event()
879 return RecordBatchesGUI::StartTime::handle_event();
882 RecordDuration::RecordDuration(RecordGUI *gui, int x, int y)
883 : RecordBatchesGUI::Duration(gui, gui->record->record_batches, x, y)
888 int RecordDuration::handle_event()
890 return RecordBatchesGUI::Duration::handle_event();
894 RecordSource::RecordSource(RecordGUI *gui, int x, int y)
895 : RecordBatchesGUI::Source(gui, gui->record->record_batches, x, y)
900 int RecordSource::handle_event()
902 gui->record->set_batch_channel_no(get_number());
903 return RecordBatchesGUI::Source::handle_event();
907 RecordNews::RecordNews(RecordGUI *gui, int x, int y)
908 : RecordBatchesGUI::News(gui->record->record_batches, x, y)
913 int RecordNews::handle_event()
915 return RecordBatchesGUI::News::handle_event();
919 RecordGUINewBatch::RecordGUINewBatch(RecordGUI *gui, int x, int y)
920 : RecordBatchesGUI::NewBatch(gui->record->record_batches, x, y)
923 set_tooltip(_("Create new clip."));
925 int RecordGUINewBatch::handle_event()
927 gui->record->new_batch();
928 return RecordBatchesGUI::NewBatch::handle_event();
932 RecordGUIDeleteBatch::RecordGUIDeleteBatch(RecordGUI *gui, int x, int y)
933 : RecordBatchesGUI::DeleteBatch(gui->record->record_batches, x, y)
936 set_tooltip(_("Delete clip."));
939 int RecordGUIDeleteBatch::handle_event()
941 gui->record->delete_batch();
942 return RecordBatchesGUI::DeleteBatch::handle_event();
946 RecordGUIStartBatches::RecordGUIStartBatches(RecordGUI *gui, int x, int y)
947 : RecordBatchesGUI::StartBatches(gui->record->record_batches, x, y)
950 set_tooltip(_("Start batch recording\nfrom the current position."));
953 int RecordGUIStartBatches::handle_event()
955 Record *record = gui->record;
956 record->start_cron_thread();
957 return RecordBatchesGUI::StartBatches::handle_event();
961 RecordGUIStopBatches::RecordGUIStopBatches(RecordGUI *gui, int x, int y)
962 : RecordBatchesGUI::StopBatches(gui->record->record_batches, x, y)
967 int RecordGUIStopBatches::handle_event()
969 Record *record = gui->record;
971 record->stop_cron_thread("Stopped");
973 return RecordBatchesGUI::StopBatches::handle_event();
977 RecordGUIActivateBatch::RecordGUIActivateBatch(RecordGUI *gui, int x, int y)
978 : RecordBatchesGUI::ActivateBatch(gui->record->record_batches, x, y)
981 set_tooltip(_("Make the highlighted\nclip active."));
983 int RecordGUIActivateBatch::handle_event()
985 gui->record->activate_batch(gui->record->editing_batch());
986 gui->update_cron_status("Idle");
987 return RecordBatchesGUI::ActivateBatch::handle_event();
991 RecordGUILabel::RecordGUILabel(RecordGUI *gui, int x, int y)
992 : BC_GenericButton(x, y, _("Label"))
999 RecordGUILabel::~RecordGUILabel()
1003 int RecordGUILabel::handle_event()
1005 gui->record->toggle_label();
1009 int RecordGUILabel::keypress_event()
1011 if(get_keypress() == 'l') {
1019 RecordGUIClearLabels::RecordGUIClearLabels(RecordGUI *gui, int x, int y)
1020 : BC_GenericButton(x, y, _("ClrLbls"))
1026 RecordGUIClearLabels::~RecordGUIClearLabels()
1030 int RecordGUIClearLabels::handle_event()
1032 gui->record->clear_labels();
1037 EndRecordThread::EndRecordThread(RecordGUI *gui)
1044 EndRecordThread::~EndRecordThread()
1046 if(Thread::running()) {
1047 window->lock_window("EndRecordThread::~EndRecordThread");
1048 window->set_done(1);
1049 window->unlock_window();
1054 void EndRecordThread::start(int is_ok)
1056 this->is_ok = is_ok;
1057 if( gui->record->writing_file ) {
1062 gui->set_done(!is_ok);
1066 void EndRecordThread::run()
1068 window = new QuestionWindow(gui->record->mwindow);
1069 window->create_objects(_("Interrupt recording in progress?"), 0);
1070 int result = window->run_window();
1072 if(result == 2) gui->set_done(!is_ok);
1076 RecordStartoverThread::RecordStartoverThread(RecordGUI *gui)
1081 RecordStartoverThread::~RecordStartoverThread()
1083 if(Thread::running()) {
1084 window->lock_window("RecordStartoverThread::~RecordStartoverThread");
1085 window->set_done(1);
1086 window->unlock_window();
1091 void RecordStartoverThread::run()
1093 Record *record = gui->record;
1094 window = new QuestionWindow(record->mwindow);
1095 window->create_objects(_("Rewind batch and overwrite?"), 0);
1096 int result = window->run_window();
1097 if(result == 2) record->start_over();
1102 int RecordGUI::set_translation(int x, int y, float z)
1104 record->video_x = x;
1105 record->video_y = y;
1106 record->video_zoom = z;
1110 void RecordGUI::reset_video()
1112 total_dropped_frames = 0;
1113 status_thread->reset_video();
1114 update_framerate(record->default_asset->frame_rate);
1117 void RecordGUI::update_dropped_frames(long value)
1119 status_thread->update_dropped_frames(value);
1122 void RecordGUI::update_frames_behind(long value)
1124 status_thread->update_frames_behind(value);
1127 void RecordGUI::update_position(double value)
1129 status_thread->update_position(value);
1132 void RecordGUI::update_framerate(double value)
1134 status_thread->update_framerate(value);
1137 void RecordGUI::update_video(int dropped, int behind)
1139 total_dropped_frames += dropped;
1140 update_dropped_frames(total_dropped_frames);
1141 update_frames_behind(behind);
1142 status_thread->update_position(record->current_display_position());
1145 void RecordGUI::reset_audio()
1147 // gui->lock_window("RecordAudio::run 2");
1149 total_clipped_samples = 0;
1150 status_thread->reset_audio();
1151 AudioDevice *adevice = record->adevice;
1152 RecordMonitorGUI *window = record->record_monitor->window;
1153 window->lock_window("RecordAudio::run 2");
1154 MeterPanel *meters = window->meters;
1156 int dmix = adevice && (adevice->get_idmix() || adevice->get_odmix());
1157 meters->init_meters(dmix);
1159 window->unlock_window();
1160 // gui->unlock_window();
1163 void RecordGUI::update_clipped_samples(long value)
1165 status_thread->update_clipped_samples(value);
1168 void RecordGUI::update_audio(int channels, double *max, int *over)
1170 // Get clipping status
1172 for( int ch=0; ch<channels && !clipped; ++ch )
1173 if( over[ch] ) clipped = 1;
1175 update_clipped_samples(++total_clipped_samples);
1177 // Update meters if monitoring
1178 if( record->metering_audio ) {
1179 RecordMonitorGUI *window = record->record_monitor->window;
1180 window->lock_window("RecordAudio::run 1");
1181 MeterPanel *meters = window->meters;
1182 int nmeters = meters->meters.total;
1183 for( int ch=0; ch<nmeters; ++ch ) {
1184 double vmax = ch < channels ? max[ch] : 0.;
1185 int vover = ch < channels ? over[ch] : 0;
1186 meters->meters.values[ch]->update(vmax, vover);
1188 window->unlock_window();
1190 // update position, if no video
1191 if( !record->default_asset->video_data )
1192 update_position(record->current_display_position());
1196 int RecordGUI::keypress_event()
1198 return record_transport->keypress_event();
1201 void RecordGUI::update_labels(double new_position)
1203 RecordLabel *prev, *next;
1205 for(prev = record->get_current_batch()->labels->last;
1207 prev = prev->previous) {
1208 if(prev->position <= new_position) break;
1211 for(next = record->get_current_batch()->labels->first;
1215 if(next->position > new_position) break;
1219 update_title(prev_label_title, prev->position);
1221 update_title(prev_label_title, -1);
1224 // update_title(next_label_title, (double)next->position / record->default_asset->sample_rate);
1226 // update_title(next_label_title, -1);
1230 int RecordGUI::update_prev_label(long new_position)
1232 update_title(prev_label_title, new_position);
1236 // int RecordGUI::update_next_label(long new_position)
1238 // update_title(next_label_title, new_position);
1241 int RecordGUI::update_title(BC_Title *title, double position)
1243 static char string[256];
1246 Units::totext(string,
1248 mwindow->edl->session->time_format,
1249 record->default_asset->sample_rate,
1250 record->default_asset->frame_rate,
1251 mwindow->edl->session->frames_per_foot);
1254 sprintf(string, "-");
1256 lock_window("RecordGUI::update_title");
1257 title->update(string);
1263 void RecordGUI::update_cron_status(const char *status)
1265 lock_window("RecordGUI::update_cron_status");
1266 cron_status->update(status);
1270 void RecordGUI::update_power_off(int value)
1272 lock_window("RecordGUI::update_power_off");
1273 power_off->update(value);
1280 // ===================================== GUI
1281 // ================================================== modes
1283 RecordGUIModeTextBox::RecordGUIModeTextBox(RecordGUIModeMenu *mode_menu,
1284 int x, int y, int w,const char *text)
1285 : BC_TextBox(x, y, w, 1, text)
1287 this->mode_menu = mode_menu;
1290 RecordGUIModeTextBox::~RecordGUIModeTextBox()
1294 int RecordGUIModeTextBox::handle_event()
1299 RecordGUIModeListBox::RecordGUIModeListBox(RecordGUIModeMenu *mode_menu)
1300 : BC_ListBox(mode_menu->textbox->get_x() + mode_menu->textbox->get_w(),
1301 mode_menu->textbox->get_y(), 100, 50, LISTBOX_TEXT,
1302 &mode_menu->modes, 0, 0, 1, 0, 1)
1304 this->mode_menu = mode_menu;
1307 RecordGUIModeListBox::~RecordGUIModeListBox()
1311 int RecordGUIModeListBox::handle_event()
1313 return mode_menu->handle_event();
1316 RecordGUIModeMenu::RecordGUIModeMenu(RecordGUI *record_gui,
1317 int x, int y, int w,const char *text)
1319 this->record_gui = record_gui;
1320 textbox = new RecordGUIModeTextBox(this,x, y, w, "");
1321 record_gui->add_subwindow(textbox);
1322 listbox = new RecordGUIModeListBox(this);
1323 record_gui->add_subwindow(listbox);
1326 RecordGUIModeMenu::~RecordGUIModeMenu()
1328 for( int i=0; i<modes.total; ++i )
1329 delete modes.values[i];
1334 void RecordGUIModeMenu::create_objects()
1336 value = RECORD_UNTIMED;
1337 modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_UNTIMED)));
1338 modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_TIMED)));
1339 textbox->update(modes.values[value]->get_text());
1342 int RecordGUIModeMenu::handle_event()
1344 value = listbox->get_selection_number(0, 0);
1345 textbox->update(modes.values[value]->get_text());
1346 textbox->handle_event();
1347 record_gui->record->set_record_mode(value);
1348 if( value == RECORD_TIMED )
1349 record_gui->batch_duration->enable();
1351 record_gui->batch_duration->disable();
1355 void RecordGUIModeMenu::update(int value)
1357 this->value = value;
1358 textbox->update(modes.values[value]->get_text());
1361 int RecordGUIModeMenu::get_w()
1363 return textbox->get_w() + listbox->get_w();
1366 int RecordGUIModeMenu::get_h()
1368 return MAX(textbox->get_h(), listbox->get_h());
1372 RecordStatusThread::RecordStatusThread(MWindow *mwindow, RecordGUI *gui)
1375 this->mwindow = mwindow;
1377 input_lock = new Condition(0, "RecordStatusThread::input_lock");
1383 RecordStatusThread::~RecordStatusThread()
1385 if(Thread::running())
1388 input_lock->unlock();
1393 void RecordStatusThread::reset_video()
1395 new_dropped_frames = 0;
1396 displayed_dropped_frames = -1;
1397 new_frames_behind = 0;
1398 displayed_frames_behind = -1;
1400 displayed_framerate = -1.;
1404 void RecordStatusThread::reset_audio()
1406 new_clipped_samples = 0;
1407 displayed_clipped_samples = -1;
1410 void RecordStatusThread::update_frames_behind(long value)
1412 if( value != displayed_frames_behind ) {
1413 new_frames_behind = value;
1414 input_lock->unlock();
1418 void RecordStatusThread::update_dropped_frames(long value)
1420 if( value != displayed_dropped_frames ) {
1421 new_dropped_frames = value;
1422 input_lock->unlock();
1426 void RecordStatusThread::update_clipped_samples(long value)
1428 if( value != displayed_clipped_samples ) {
1429 new_clipped_samples = value;
1430 input_lock->unlock();
1434 void RecordStatusThread::update_position(double value)
1436 this->new_position = value;
1437 input_lock->unlock();
1440 void RecordStatusThread::update_framerate(double value)
1442 if( value != displayed_framerate ) {
1443 new_framerate = value;
1444 input_lock->unlock();
1450 void RecordStatusThread::
1451 update_status_string(const char *fmt, T &new_value, T &displayed_value, BC_Title *widgit)
1453 if( new_value >= 0 ) {
1454 if( displayed_value != new_value ) {
1455 displayed_value = new_value;
1458 sprintf(string, fmt, displayed_value);
1459 gui->lock_window("RecordStatusThread::run 1");
1460 widgit->update(string);
1461 gui->unlock_window();
1468 void RecordStatusThread::run()
1471 input_lock->lock("RecordStatusThread::run");
1473 gui->record->window_lock->lock("RecordStatusThread::run");
1474 update_status_string("%d", new_dropped_frames, displayed_dropped_frames,
1475 gui->frames_dropped);
1476 update_status_string("%d", new_frames_behind, displayed_frames_behind,
1477 gui->frames_behind);
1478 update_status_string("%d", new_clipped_samples, displayed_clipped_samples,
1479 gui->samples_clipped);
1480 update_status_string("%0.2f", new_framerate, displayed_framerate,
1482 if( new_position >= 0 ) {
1483 gui->update_title(gui->position_title, new_position);
1484 gui->update_labels(new_position);
1487 gui->record->window_lock->unlock();
1492 void RecordGUI::start_flash_batch()
1494 if( batch_flash ) return;
1495 batch_flash = new RecordGUIFlash(this);
1498 void RecordGUI::stop_flash_batch()
1500 if( !batch_flash ) return;
1505 void RecordGUI::flash_batch()
1507 lock_window("void RecordGUI::flash_batch");
1508 int cur_batch = record->current_batch();
1509 if( cur_batch >= 0 && cur_batch < batch_bay->count()) {
1510 flash_color = flash_color == GREEN ? RED : GREEN;
1511 //printf("RecordGUI::flash_batch %x\n", flash_color);
1512 batch_bay->set_row_color(cur_batch, flash_color);
1513 batch_bay->update_batch_news(cur_batch);
1519 RecordGUIFlash(RecordGUI *record_gui)
1522 this->record_gui = record_gui;
1523 flash_lock = new Condition(0,"RecordGUIFlash::flash_lock");
1531 if( Thread::running() ) {
1533 flash_lock->unlock();
1540 void RecordGUIFlash::run()
1543 record_gui->flash_batch();
1552 RecordGUIDCOffset::RecordGUIDCOffset(MWindow *mwindow, int y)
1553 : BC_Button(230, y, mwindow->theme->calibrate_data)
1557 RecordGUIDCOffset::~RecordGUIDCOffset() {}
1559 int RecordGUIDCOffset::handle_event()
1564 int RecordGUIDCOffset::keypress_event() { return 0; }
1566 RecordGUIDCOffsetText::RecordGUIDCOffsetText(char *text, int y, int number)
1567 : BC_TextBox(30, y+1, 67, 1, text, 0)
1569 this->number = number;
1572 RecordGUIDCOffsetText::~RecordGUIDCOffsetText()
1576 int RecordGUIDCOffsetText::handle_event()
1581 RecordGUIReset::RecordGUIReset(MWindow *mwindow, RecordGUI *gui, int y)
1582 : BC_Button(400, y, mwindow->theme->over_button)
1583 { this->gui = gui; }
1585 RecordGUIReset::~RecordGUIReset()
1589 int RecordGUIReset::handle_event()
1594 RecordGUIResetTranslation::RecordGUIResetTranslation(MWindow *mwindow, RecordGUI *gui, int y)
1595 : BC_Button(250, y, mwindow->theme->reset_data)
1600 RecordGUIResetTranslation::~RecordGUIResetTranslation()
1604 int RecordGUIResetTranslation::handle_event()
1606 gui->set_translation(0, 0, 1);