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"
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,
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 TRACE("RecordGUI::~RecordGUI 1");
120 delete status_thread;
124 delete startover_thread;
125 delete interrupt_thread;
127 delete batch_duration;
129 TRACE("RecordGUI::~RecordGUI 2");
133 void RecordGUI::create_objects()
135 char string[BCTEXTLEN];
137 Asset *asset = record->default_asset;
138 lock_window("RecordGUI::create_objects");
139 status_thread = new RecordStatusThread(mwindow, this);
140 status_thread->start();
141 set_icon(mwindow->theme->get_image("record_icon"));
143 mwindow->theme->get_recordgui_sizes(this, get_w(), get_h());
144 //printf("RecordGUI::create_objects 1\n");
145 mwindow->theme->draw_rwindow_bg(this);
151 int pad = max(BC_TextBox::calculate_h(this, MEDIUMFONT, 1, 1),
152 BC_Title::calculate_h(this, "X")) + 5;
156 add_subwindow(title = new BC_Title(x, y, _("Path:")));
157 x1 = max(title->get_w(), x1);
159 add_subwindow(title = new BC_Title(x, y, _("Start time:")));
160 x1 = max(title->get_w(), x1);
162 add_subwindow(title = new BC_Title(x, y, _("Duration time:")));
163 x1 = max(title->get_w(), x1);
165 add_subwindow(title = new BC_Title(x, y, _("Source:")));
166 x1 = max(title->get_w(), x1);
168 add_subwindow(title = new BC_Title(x, y, _("Mode:")));
169 x1 = max(title->get_w(), x1);
171 add_subwindow(title = new BC_Title(x, y, _("Transport:")));
172 x1 = max(title->get_w(), x1);
175 button_y = max(y, button_y);
182 add_subwindow(batch_path = new RecordPath(this, x, y));
183 add_subwindow(batch_browse = new BrowseButton(mwindow,
186 batch_path->get_x() + batch_path->get_w(),
189 _(PROGRAM_NAME ": Record path"),
190 _("Select a file to record to:"),
192 x2 = max(x2, batch_path->get_w() + batch_browse->get_w());
194 batch_start = new RecordStart(this, x, y);
195 batch_start->create_objects();
196 x2 = max(x2, batch_start->get_w());
198 batch_duration = new RecordDuration(this, x, y);
199 batch_duration->create_objects();
200 x2 = max(x2, batch_duration->get_w());
202 batch_source = new RecordSource(this, x, y);
203 batch_source->create_objects();
204 x2 = max(x2, batch_source->get_w());
206 batch_mode = new RecordGUIModeMenu(this, x, y, 200, "");
207 batch_mode->create_objects();
208 x2 = max(x2, batch_mode->get_w());
210 record_transport = new RecordTransport(mwindow,
212 record_transport->create_objects();
213 x2 = max(x2, record_transport->get_w());
218 // Compression settings
222 pad = BC_Title::calculate_h(this, "X") + 5;
223 add_subwindow(title = new BC_Title(x, y, _("Format:")));
224 x3 = max(title->get_w(), x3);
227 if(asset->audio_data)
229 add_subwindow(title = new BC_Title(x, y, _("Audio compression:")));
230 x3 = max(title->get_w(), x3);
232 add_subwindow(title = new BC_Title(x, y, _("Samplerate:")));
233 x3 = max(title->get_w(), x3);
235 add_subwindow(title = new BC_Title(x, y, _("Clipped samples:")));
236 x3 = max(title->get_w(), x3);
240 if(asset->video_data)
242 add_subwindow(title = new BC_Title(x, y, _("Video compression:")));
243 x3 = max(title->get_w(), x3);
245 add_subwindow(title = new BC_Title(x, y, _("Framerate:")));
246 x3 = max(title->get_w(), x3);
248 add_subwindow(title = new BC_Title(x, y, _("Frames dropped:")));
249 x3 = max(title->get_w(), x3);
251 add_subwindow(title = new BC_Title(x, y, _("Frames behind:")));
252 x3 = max(title->get_w(), x3);
256 add_subwindow(title = new BC_Title(x, y, _("Position:")));
257 x3 = max(title->get_w(), x3);
259 add_subwindow(title = new BC_Title(x, y, _("Prev label:")));
260 x3 = max(title->get_w(), x3);
263 button_y = max(y, button_y);
265 x = x3 + x2 + x1 + 40;
267 add_subwindow(new BC_Title(x, y,
268 File::formattostr(mwindow->plugindb, asset->format),
270 mwindow->theme->recordgui_fixed_color));
273 if(asset->audio_data) {
274 add_subwindow(new BC_Title(x, y,
275 File::bitstostr(asset->bits),
277 mwindow->theme->recordgui_fixed_color));
280 sprintf(string, "%d", asset->sample_rate);
281 add_subwindow(new BC_Title(x, y,
283 mwindow->theme->recordgui_fixed_color));
286 add_subwindow(samples_clipped = new BC_Title(x, y,
288 mwindow->theme->recordgui_variable_color));
292 if(asset->video_data) {
293 add_subwindow(new BC_Title(x, y,
294 asset->format == FILE_MPEG ? _("File Capture") :
295 File::compressiontostr(asset->vcodec),
297 mwindow->theme->recordgui_fixed_color));
300 sprintf(string, "%0.2f", asset->frame_rate);
301 add_subwindow(framerate = new BC_Title(x, y,
303 mwindow->theme->recordgui_fixed_color));
306 add_subwindow(frames_dropped = new BC_Title(x, y,
308 mwindow->theme->recordgui_variable_color));
310 add_subwindow(frames_behind = new BC_Title(x, y,
312 mwindow->theme->recordgui_variable_color));
316 add_subwindow(position_title = new BC_Title(x, y,
318 mwindow->theme->recordgui_variable_color));
321 add_subwindow(prev_label_title = new BC_Title(x, y,
322 _("None"), MEDIUMFONT,
323 mwindow->theme->recordgui_variable_color));
326 button_y = max(y, button_y);
332 add_subwindow(title = new BC_Title(x,y, _("Batches:")));
333 int y_max = y + title->get_h(); x1 = x;
334 x += title->get_w() + 5;
335 add_subwindow(activate_batch = new RecordGUIActivateBatch(this, x, y));
336 x += activate_batch->get_w();
337 y_max = max(y_max, y + activate_batch->get_h());
338 add_subwindow(start_batches = new RecordGUIStartBatches(this, x, y));
339 y_max = max(y_max, y + start_batches->get_h()); x2 = x;
340 x += start_batches->get_w();
341 add_subwindow(new_batch = new RecordGUINewBatch(this, x, y));
342 y_max = max(y_max, y + new_batch->get_h()); x3 = x;
343 x += new_batch->get_w(); int x4 = x;
344 add_subwindow(label_button = new RecordGUILabel(this, x, y));
345 y_max = max(y_max, y + label_button->get_h());
347 int y1 = y_max, y2 = y1 + 5;
348 add_subwindow(title = new BC_Title(x1,y2, _("Cron:")));
349 y_max = max(y_max, y2 + title->get_h());
350 x1 += title->get_w() + 5;
351 add_subwindow(cron_status = new BC_Title(x1,y2, _("Idle"), MEDIUMFONT,
352 mwindow->theme->recordgui_variable_color));
353 y_max = max(y_max, y2 + cron_status->get_h());
354 add_subwindow(stop_batches = new RecordGUIStopBatches(this, x2, y1));
355 y_max = max(y_max, y1 + stop_batches->get_h());
356 add_subwindow(delete_batch = new RecordGUIDeleteBatch(this, x3, y1));
357 y_max = max(y_max, y1 + delete_batch->get_h());
358 add_subwindow(clrlbls_button = new RecordGUIClearLabels(this, x4, y1));
359 y_max = max(y_max, y1 + clrlbls_button->get_h());
369 if(asset->video_data) {
370 add_subwindow(drop_frames = new RecordGUIDropFrames(this, x, y));
371 add_subwindow(fill_frames = new RecordGUIFillFrames(this, x, y1));
372 x += drop_frames->get_w() + 5; x1 = x;
373 add_subwindow(monitor_video = new RecordGUIMonitorVideo(this, x, y));
374 x += monitor_video->get_w() + 5;
377 if(asset->audio_data) {
378 add_subwindow(monitor_audio = new RecordGUIMonitorAudio(this, x, y));
379 x += monitor_audio->get_w() + 5;
380 add_subwindow(meter_audio = new RecordGUIAudioMeters(this, x, y));
381 x += meter_audio->get_w() + 5;
384 add_subwindow(power_off = new RecordGUIPowerOff(this, x1, y1));
385 x1 += power_off->get_w() + 10;
386 add_subwindow(commercial_check = new RecordGUICommCheck(this, x1, y1));
392 y = y1 + fill_frames->get_h();
393 else if( monitor_audio )
394 y += monitor_audio->get_h();
396 int bottom_margin = max(BC_OKButton::calculate_h(),
397 LoadMode::calculate_h(this, mwindow->theme)) + 5;
400 add_subwindow(batch_bay = new RecordGUIBatches(this, x, y,
401 get_w() - 20, get_h() - y - bottom_margin - 10));
402 y += batch_bay->get_h() + 5;
403 record->record_batches.gui = batch_bay;
404 batch_bay->update_batches(-1);
407 int loadmode_w = LoadMode::calculate_w(this, mwindow->theme, 1, 0);
408 load_mode = new LoadMode(mwindow, this,
409 get_w() / 2 - loadmode_w / 2, y,
410 &record->load_mode, 1, 0);
411 load_mode->create_objects();
412 y += load_mode->get_h() + 5;
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 // Recompute batch list based on previous extents
469 int bottom_margin = mwindow->session->rwindow_h -
472 int mode_margin = mwindow->session->rwindow_h - load_mode->get_y();
473 mwindow->session->rwindow_x = get_x();
474 mwindow->session->rwindow_y = get_y();
475 mwindow->session->rwindow_w = w;
476 mwindow->session->rwindow_h = h;
477 mwindow->theme->get_recordgui_sizes(this, w, h);
478 mwindow->theme->draw_rwindow_bg(this);
480 int new_h = mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y();
481 if(new_h < 10) new_h = 10;
482 batch_bay->reposition_window(batch_bay->get_x(),
484 mwindow->session->rwindow_w - 20,
485 mwindow->session->rwindow_h - bottom_margin - batch_bay->get_y());
487 load_mode->reposition_window(mwindow->session->rwindow_w / 2 -
488 mwindow->theme->loadmode_w / 2,
489 mwindow->session->rwindow_h - mode_margin);
495 void RecordGUI::update_batch_tools()
497 lock_window("RecordGUI::update_batch_tools");
498 //printf("RecordGUI::update_batch_tools 1\n");
499 Batch *batch = get_editing_batch();
500 batch_path->update(batch->asset->path);
502 // File is open in editing batch
503 // if(current_batch() == editing_batch() && record->file)
504 // batch_path->disable();
506 // batch_path->enable();
508 batch_start->update(&batch->start_day, &batch->start_time);
509 batch_duration->update(0, &batch->duration);
510 batch_source->update(batch->get_source_text());
511 batch_mode->update(batch->record_mode);
512 if( batch_mode->value == RECORD_TIMED )
513 batch_duration->enable();
515 batch_duration->disable();
520 void RecordGUI::enable_batch_buttons()
522 lock_window("RecordGUI::enable_batch_buttons");
524 delete_batch->enable();
525 start_batches->enable();
526 stop_batches->disable();
527 activate_batch->enable();
531 void RecordGUI::disable_batch_buttons()
533 lock_window("RecordGUI::disable_batch_buttons");
534 new_batch->disable();
535 delete_batch->disable();
536 start_batches->disable();
537 stop_batches->enable();
538 activate_batch->disable();
542 RecordGUIBatches::RecordGUIBatches(RecordGUI *gui, int x, int y, int w, int h)
543 : RecordBatchesGUI(gui->record->record_batches, x, y, w, h)
548 // Do nothing for double clicks to protect active batch
549 int RecordGUIBatches::handle_event()
554 int RecordGUIBatches::selection_changed()
556 RecordBatchesGUI::selection_changed();
557 gui->update_batch_tools();
562 RecordGUISave::RecordGUISave(RecordGUI *gui)
564 gui->get_h() - BC_WindowBase::get_resources()->ok_images[0]->get_h() - 10,
565 BC_WindowBase::get_resources()->ok_images)
567 set_tooltip(_("Save the recording and quit."));
571 int RecordGUISave::handle_event()
577 int RecordGUISave::keypress_event()
579 // if(get_keypress() == RETURN)
587 RecordGUICancel::RecordGUICancel(RecordGUI *gui)
588 : BC_CancelButton(gui)
590 set_tooltip(_("Quit without pasting into project."));
594 int RecordGUICancel::handle_event()
596 gui->interrupt_thread->start(0);
600 int RecordGUICancel::keypress_event()
602 if(get_keypress() == ESC)
612 RecordGUIOK::RecordGUIOK(RecordGUI *gui)
615 set_tooltip(_("Quit and paste into project."));
619 int RecordGUIOK::handle_event()
621 gui->interrupt_thread->start(1);
626 RecordGUIStartOver::RecordGUIStartOver(RecordGUI *gui, int x, int y)
627 : BC_GenericButton(x, y, _("Start Over"))
629 set_tooltip(_("Rewind the current file and erase."));
632 RecordGUIStartOver::~RecordGUIStartOver()
636 int RecordGUIStartOver::handle_event()
638 if(!gui->startover_thread->running())
639 gui->startover_thread->start();
644 RecordGUIDropFrames::RecordGUIDropFrames(RecordGUI *gui, int x, int y)
645 : BC_CheckBox(x, y, gui->record->drop_overrun_frames, _("drop overrun frames"))
647 this->set_underline(0);
649 set_tooltip(_("Drop input frames when behind."));
652 int RecordGUIDropFrames::handle_event()
654 gui->record->drop_overrun_frames = get_value();
658 int RecordGUIDropFrames::keypress_event()
660 if(get_keypress() == 'd') {
661 set_value(get_value() ? 0 : 1);
668 RecordGUIFillFrames::RecordGUIFillFrames(RecordGUI *gui, int x, int y)
669 : BC_CheckBox(x, y, gui->record->fill_underrun_frames, _("fill underrun frames"))
671 this->set_underline(0);
673 set_tooltip(_("Write extra frames when behind."));
676 int RecordGUIFillFrames::handle_event()
678 gui->record->fill_underrun_frames = get_value();
682 int RecordGUIFillFrames::keypress_event()
684 if(get_keypress() == 'f') {
685 set_value(get_value() ? 0 : 1);
692 RecordGUIPowerOff::RecordGUIPowerOff(RecordGUI *gui, int x, int y)
693 : BC_CheckBox(x, y, gui->record->power_off, _("poweroff when done"))
695 this->set_underline(0);
697 set_tooltip(_("poweroff system when batch record done."));
700 int RecordGUIPowerOff::handle_event()
702 gui->record->power_off = get_value();
706 int RecordGUIPowerOff::keypress_event()
708 if(get_keypress() == 'p') {
709 set_value(get_value() ? 0 : 1);
717 RecordGUICommCheck::RecordGUICommCheck(RecordGUI *gui, int x, int y)
718 : BC_CheckBox(x, y, gui->record->commercial_check, _("check for ads"))
720 this->set_underline(0);
722 set_tooltip(_("check for commercials."));
725 int RecordGUICommCheck::handle_event()
727 gui->record->update_skimming(get_value());
732 int RecordGUICommCheck::keypress_event()
734 if(get_keypress() == 'c') {
735 set_value(get_value() ? 0 : 1);
736 gui->record->update_skimming(get_value());
744 RecordGUIMonitorVideo::RecordGUIMonitorVideo(RecordGUI *gui, int x, int y)
745 : BC_CheckBox(x, y, gui->record->monitor_video, _("Monitor video"))
747 this->set_underline(8);
751 int RecordGUIMonitorVideo::handle_event()
753 // Video capture constitutively, just like audio, but only flash on screen if 1
754 int mode = get_value();
755 Record *record = gui->record;
756 record->set_video_monitoring(mode);
757 if(record->monitor_video) {
759 BC_Window *window = record->record_monitor->window;
760 window->lock_window("RecordGUIMonitorVideo::handle_event");
761 window->show_window();
762 window->raise_window();
764 window->unlock_window();
765 lock_window("RecordGUIMonitorVideo::handle_event");
766 record->video_window_open = 1;
772 int RecordGUIMonitorVideo::keypress_event()
774 if(get_keypress() == 'v') {
775 set_value(get_value() ? 0 : 1);
784 RecordGUIMonitorAudio::RecordGUIMonitorAudio(RecordGUI *gui, int x, int y)
785 : BC_CheckBox(x, y, gui->record->monitor_audio, _("Monitor audio"))
787 this->set_underline(8);
791 int RecordGUIMonitorAudio::handle_event()
793 int mode = get_value();
794 Record *record = gui->record;
795 record->set_audio_monitoring(mode);
796 if(record->monitor_audio) {
798 BC_Window *window = record->record_monitor->window;
799 window->lock_window("RecordGUIMonitorAudio::handle_event");
800 window->show_window();
801 window->raise_window();
803 window->unlock_window();
804 lock_window("RecordGUIMonitorAudio::handle_event");
805 record->video_window_open = 1;
810 int RecordGUIMonitorAudio::keypress_event()
812 if(get_keypress() == 'a') {
813 set_value(get_value() ? 0 : 1);
821 RecordGUIAudioMeters::RecordGUIAudioMeters(RecordGUI *gui, int x, int y)
822 : BC_CheckBox(x, y, gui->record->metering_audio, _("Audio meters"))
824 this->set_underline(6);
828 int RecordGUIAudioMeters::handle_event()
830 int mode = get_value();
831 Record *record = gui->record;
832 record->set_audio_metering(mode);
833 if(record->metering_audio) {
835 BC_Window *window = record->record_monitor->window;
836 window->lock_window("RecordGUIAudioMeters::handle_event");
837 window->show_window();
838 window->raise_window();
840 window->unlock_window();
841 lock_window("RecordGUIAudioMeters::handle_event");
842 record->video_window_open = 1;
847 int RecordGUIAudioMeters::keypress_event()
849 if(get_keypress() == 'm') {
850 set_value(get_value() ? 0 : 1);
857 RecordPath::RecordPath(RecordGUI *gui, int x, int y)
858 : RecordBatchesGUI::Path(gui->record->record_batches, x, y)
863 int RecordPath::handle_event()
865 return RecordBatchesGUI::Path::handle_event();
869 RecordStart::RecordStart(RecordGUI *gui, int x, int y)
870 : RecordBatchesGUI::StartTime(gui, gui->record->record_batches, x, y)
875 int RecordStart::handle_event()
877 return RecordBatchesGUI::StartTime::handle_event();
880 RecordDuration::RecordDuration(RecordGUI *gui, int x, int y)
881 : RecordBatchesGUI::Duration(gui, gui->record->record_batches, x, y)
886 int RecordDuration::handle_event()
888 return RecordBatchesGUI::Duration::handle_event();
892 RecordSource::RecordSource(RecordGUI *gui, int x, int y)
893 : RecordBatchesGUI::Source(gui, gui->record->record_batches, x, y)
898 int RecordSource::handle_event()
900 gui->record->set_batch_channel_no(get_number());
901 return RecordBatchesGUI::Source::handle_event();
905 RecordNews::RecordNews(RecordGUI *gui, int x, int y)
906 : RecordBatchesGUI::News(gui->record->record_batches, x, y)
911 int RecordNews::handle_event()
913 return RecordBatchesGUI::News::handle_event();
917 RecordGUINewBatch::RecordGUINewBatch(RecordGUI *gui, int x, int y)
918 : RecordBatchesGUI::NewBatch(gui->record->record_batches, x, y)
921 set_tooltip(_("Create new clip."));
923 int RecordGUINewBatch::handle_event()
925 gui->record->new_batch();
926 return RecordBatchesGUI::NewBatch::handle_event();
930 RecordGUIDeleteBatch::RecordGUIDeleteBatch(RecordGUI *gui, int x, int y)
931 : RecordBatchesGUI::DeleteBatch(gui->record->record_batches, x, y)
934 set_tooltip(_("Delete clip."));
937 int RecordGUIDeleteBatch::handle_event()
939 gui->record->delete_batch();
940 return RecordBatchesGUI::DeleteBatch::handle_event();
944 RecordGUIStartBatches::RecordGUIStartBatches(RecordGUI *gui, int x, int y)
945 : RecordBatchesGUI::StartBatches(gui->record->record_batches, x, y)
948 set_tooltip(_("Start batch recording\nfrom the current position."));
951 int RecordGUIStartBatches::handle_event()
953 Record *record = gui->record;
954 record->start_cron_thread();
955 return RecordBatchesGUI::StartBatches::handle_event();
959 RecordGUIStopBatches::RecordGUIStopBatches(RecordGUI *gui, int x, int y)
960 : RecordBatchesGUI::StopBatches(gui->record->record_batches, x, y)
965 int RecordGUIStopBatches::handle_event()
967 Record *record = gui->record;
969 record->stop_cron_thread(_("Stopped"));
971 return RecordBatchesGUI::StopBatches::handle_event();
975 RecordGUIActivateBatch::RecordGUIActivateBatch(RecordGUI *gui, int x, int y)
976 : RecordBatchesGUI::ActivateBatch(gui->record->record_batches, x, y)
979 set_tooltip(_("Make the highlighted\nclip active."));
981 int RecordGUIActivateBatch::handle_event()
983 gui->record->activate_batch(gui->record->editing_batch());
984 gui->update_cron_status(_("Idle"));
985 return RecordBatchesGUI::ActivateBatch::handle_event();
989 RecordGUILabel::RecordGUILabel(RecordGUI *gui, int x, int y)
990 : BC_GenericButton(x, y, _("Label"))
997 RecordGUILabel::~RecordGUILabel()
1001 int RecordGUILabel::handle_event()
1003 gui->record->toggle_label();
1007 int RecordGUILabel::keypress_event()
1009 if(get_keypress() == 'l') {
1017 RecordGUIClearLabels::RecordGUIClearLabels(RecordGUI *gui, int x, int y)
1018 : BC_GenericButton(x, y, _("ClrLbls"))
1024 RecordGUIClearLabels::~RecordGUIClearLabels()
1028 int RecordGUIClearLabels::handle_event()
1030 gui->record->clear_labels();
1035 EndRecordThread::EndRecordThread(RecordGUI *gui)
1042 EndRecordThread::~EndRecordThread()
1044 if(Thread::running()) {
1045 window->lock_window("EndRecordThread::~EndRecordThread");
1046 window->set_done(1);
1047 window->unlock_window();
1052 void EndRecordThread::start(int is_ok)
1054 this->is_ok = is_ok;
1055 if( gui->record->writing_file ) {
1060 gui->set_done(!is_ok);
1064 void EndRecordThread::run()
1066 window = new QuestionWindow(gui->record->mwindow);
1067 window->create_objects(_("Interrupt recording in progress?"), 0);
1068 int result = window->run_window();
1070 if(result == 2) gui->set_done(!is_ok);
1074 RecordStartoverThread::RecordStartoverThread(RecordGUI *gui)
1079 RecordStartoverThread::~RecordStartoverThread()
1081 if(Thread::running()) {
1082 window->lock_window("RecordStartoverThread::~RecordStartoverThread");
1083 window->set_done(1);
1084 window->unlock_window();
1089 void RecordStartoverThread::run()
1091 Record *record = gui->record;
1092 window = new QuestionWindow(record->mwindow);
1093 window->create_objects(_("Rewind batch and overwrite?"), 0);
1094 int result = window->run_window();
1095 if(result == 2) record->start_over();
1100 int RecordGUI::set_translation(int x, int y, float z)
1102 record->video_x = x;
1103 record->video_y = y;
1104 record->video_zoom = z;
1108 void RecordGUI::reset_video()
1110 total_dropped_frames = 0;
1111 status_thread->reset_video();
1112 update_framerate(record->default_asset->frame_rate);
1115 void RecordGUI::update_dropped_frames(long value)
1117 status_thread->update_dropped_frames(value);
1120 void RecordGUI::update_frames_behind(long value)
1122 status_thread->update_frames_behind(value);
1125 void RecordGUI::update_position(double value)
1127 status_thread->update_position(value);
1130 void RecordGUI::update_framerate(double value)
1132 status_thread->update_framerate(value);
1135 void RecordGUI::update_video(int dropped, int behind)
1137 total_dropped_frames += dropped;
1138 update_dropped_frames(total_dropped_frames);
1139 update_frames_behind(behind);
1140 status_thread->update_position(record->current_display_position());
1143 void RecordGUI::reset_audio()
1145 // gui->lock_window("RecordAudio::run 2");
1147 total_clipped_samples = 0;
1148 status_thread->reset_audio();
1149 AudioDevice *adevice = record->adevice;
1150 RecordMonitorGUI *window = record->record_monitor->window;
1151 window->lock_window("RecordAudio::run 2");
1152 MeterPanel *meters = window->meters;
1154 int dmix = adevice && (adevice->get_idmix() || adevice->get_odmix());
1155 meters->init_meters(dmix);
1157 window->unlock_window();
1158 // gui->unlock_window();
1161 void RecordGUI::update_clipped_samples(long value)
1163 status_thread->update_clipped_samples(value);
1166 void RecordGUI::update_audio(int channels, double *max, int *over)
1168 // Get clipping status
1170 for( int ch=0; ch<channels && !clipped; ++ch )
1171 if( over[ch] ) clipped = 1;
1173 update_clipped_samples(++total_clipped_samples);
1175 // Update meters if monitoring
1176 if( record->metering_audio ) {
1177 RecordMonitorGUI *window = record->record_monitor->window;
1178 window->lock_window("RecordAudio::run 1");
1179 MeterPanel *meters = window->meters;
1180 int nmeters = meters->meters.total;
1181 for( int ch=0; ch<nmeters; ++ch ) {
1182 double vmax = ch < channels ? max[ch] : 0.;
1183 int vover = ch < channels ? over[ch] : 0;
1184 meters->meters.values[ch]->update(vmax, vover);
1186 window->unlock_window();
1188 // update position, if no video
1189 if( !record->default_asset->video_data )
1190 update_position(record->current_display_position());
1194 int RecordGUI::keypress_event()
1196 return record_transport->keypress_event();
1199 void RecordGUI::update_labels(double new_position)
1201 RecordLabel *prev, *next;
1203 for(prev = record->get_current_batch()->labels->last;
1205 prev = prev->previous) {
1206 if(prev->position <= new_position) break;
1209 for(next = record->get_current_batch()->labels->first;
1213 if(next->position > new_position) break;
1217 update_title(prev_label_title, prev->position);
1219 update_title(prev_label_title, -1);
1222 // update_title(next_label_title, (double)next->position / record->default_asset->sample_rate);
1224 // update_title(next_label_title, -1);
1228 int RecordGUI::update_prev_label(long new_position)
1230 update_title(prev_label_title, new_position);
1234 // int RecordGUI::update_next_label(long new_position)
1236 // update_title(next_label_title, new_position);
1239 int RecordGUI::update_title(BC_Title *title, double position)
1241 static char string[256];
1244 Units::totext(string,
1246 mwindow->edl->session->time_format,
1247 record->default_asset->sample_rate,
1248 record->default_asset->frame_rate,
1249 mwindow->edl->session->frames_per_foot);
1252 sprintf(string, "-");
1254 lock_window("RecordGUI::update_title");
1255 title->update(string);
1261 void RecordGUI::update_cron_status(const char *status)
1263 lock_window("RecordGUI::update_cron_status");
1264 cron_status->update(status);
1268 void RecordGUI::update_power_off(int value)
1270 lock_window("RecordGUI::update_power_off");
1271 power_off->update(value);
1278 // ===================================== GUI
1279 // ================================================== modes
1281 RecordGUIModeTextBox::RecordGUIModeTextBox(RecordGUIModeMenu *mode_menu,
1282 int x, int y, int w,const char *text)
1283 : BC_TextBox(x, y, w, 1, text)
1285 this->mode_menu = mode_menu;
1288 RecordGUIModeTextBox::~RecordGUIModeTextBox()
1292 int RecordGUIModeTextBox::handle_event()
1297 RecordGUIModeListBox::RecordGUIModeListBox(RecordGUIModeMenu *mode_menu)
1298 : BC_ListBox(mode_menu->textbox->get_x() + mode_menu->textbox->get_w(),
1299 mode_menu->textbox->get_y(), 100, 50, LISTBOX_TEXT,
1300 &mode_menu->modes, 0, 0, 1, 0, 1)
1302 this->mode_menu = mode_menu;
1305 RecordGUIModeListBox::~RecordGUIModeListBox()
1309 int RecordGUIModeListBox::handle_event()
1311 return mode_menu->handle_event();
1314 RecordGUIModeMenu::RecordGUIModeMenu(RecordGUI *record_gui,
1315 int x, int y, int w,const char *text)
1317 this->record_gui = record_gui;
1318 textbox = new RecordGUIModeTextBox(this,x, y, w, "");
1319 record_gui->add_subwindow(textbox);
1320 listbox = new RecordGUIModeListBox(this);
1321 record_gui->add_subwindow(listbox);
1324 RecordGUIModeMenu::~RecordGUIModeMenu()
1326 for( int i=0; i<modes.total; ++i )
1327 delete modes.values[i];
1332 void RecordGUIModeMenu::create_objects()
1334 value = RECORD_UNTIMED;
1335 modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_UNTIMED)));
1336 modes.append(new BC_ListBoxItem(Batch::mode_to_text(RECORD_TIMED)));
1337 textbox->update(modes.values[value]->get_text());
1340 int RecordGUIModeMenu::handle_event()
1342 value = listbox->get_selection_number(0, 0);
1343 textbox->update(modes.values[value]->get_text());
1344 textbox->handle_event();
1345 record_gui->record->set_record_mode(value);
1346 if( value == RECORD_TIMED )
1347 record_gui->batch_duration->enable();
1349 record_gui->batch_duration->disable();
1353 void RecordGUIModeMenu::update(int value)
1355 this->value = value;
1356 textbox->update(modes.values[value]->get_text());
1359 int RecordGUIModeMenu::get_w()
1361 return textbox->get_w() + listbox->get_w();
1364 int RecordGUIModeMenu::get_h()
1366 return MAX(textbox->get_h(), listbox->get_h());
1370 RecordStatusThread::RecordStatusThread(MWindow *mwindow, RecordGUI *gui)
1373 this->mwindow = mwindow;
1375 input_lock = new Condition(0, "RecordStatusThread::input_lock");
1381 RecordStatusThread::~RecordStatusThread()
1383 if(Thread::running())
1386 input_lock->unlock();
1391 void RecordStatusThread::reset_video()
1393 new_dropped_frames = 0;
1394 displayed_dropped_frames = -1;
1395 new_frames_behind = 0;
1396 displayed_frames_behind = -1;
1398 displayed_framerate = -1.;
1402 void RecordStatusThread::reset_audio()
1404 new_clipped_samples = 0;
1405 displayed_clipped_samples = -1;
1408 void RecordStatusThread::update_frames_behind(long value)
1410 if( value != displayed_frames_behind ) {
1411 new_frames_behind = value;
1412 input_lock->unlock();
1416 void RecordStatusThread::update_dropped_frames(long value)
1418 if( value != displayed_dropped_frames ) {
1419 new_dropped_frames = value;
1420 input_lock->unlock();
1424 void RecordStatusThread::update_clipped_samples(long value)
1426 if( value != displayed_clipped_samples ) {
1427 new_clipped_samples = value;
1428 input_lock->unlock();
1432 void RecordStatusThread::update_position(double value)
1434 this->new_position = value;
1435 input_lock->unlock();
1438 void RecordStatusThread::update_framerate(double value)
1440 if( value != displayed_framerate ) {
1441 new_framerate = value;
1442 input_lock->unlock();
1448 void RecordStatusThread::
1449 update_status_string(const char *fmt, T &new_value, T &displayed_value, BC_Title *widgit)
1451 if( new_value >= 0 ) {
1452 if( displayed_value != new_value ) {
1453 displayed_value = new_value;
1456 sprintf(string, fmt, displayed_value);
1457 gui->lock_window("RecordStatusThread::run 1");
1458 widgit->update(string);
1459 gui->unlock_window();
1466 void RecordStatusThread::run()
1469 input_lock->lock("RecordStatusThread::run");
1471 gui->record->window_lock->lock("RecordStatusThread::run");
1472 update_status_string("%d", new_dropped_frames, displayed_dropped_frames,
1473 gui->frames_dropped);
1474 update_status_string("%d", new_frames_behind, displayed_frames_behind,
1475 gui->frames_behind);
1476 update_status_string("%d", new_clipped_samples, displayed_clipped_samples,
1477 gui->samples_clipped);
1478 update_status_string("%0.2f", new_framerate, displayed_framerate,
1480 if( new_position >= 0 ) {
1481 gui->update_title(gui->position_title, new_position);
1482 gui->update_labels(new_position);
1485 gui->record->window_lock->unlock();
1490 void RecordGUI::start_flash_batch()
1492 if( batch_flash ) return;
1493 batch_flash = new RecordGUIFlash(this);
1496 void RecordGUI::stop_flash_batch()
1498 if( !batch_flash ) return;
1503 void RecordGUI::flash_batch()
1505 lock_window("void RecordGUI::flash_batch");
1506 int cur_batch = record->current_batch();
1507 if( cur_batch >= 0 && cur_batch < batch_bay->count()) {
1508 flash_color = flash_color == GREEN ? RED : GREEN;
1509 //printf("RecordGUI::flash_batch %x\n", flash_color);
1510 batch_bay->set_row_color(cur_batch, flash_color);
1511 batch_bay->update_batch_news(cur_batch);
1517 RecordGUIFlash(RecordGUI *record_gui)
1520 this->record_gui = record_gui;
1521 flash_lock = new Condition(0,"RecordGUIFlash::flash_lock");
1529 if( Thread::running() ) {
1531 flash_lock->unlock();
1538 void RecordGUIFlash::run()
1541 record_gui->flash_batch();
1550 RecordGUIDCOffset::RecordGUIDCOffset(MWindow *mwindow, int y)
1551 : BC_Button(230, y, mwindow->theme->calibrate_data)
1555 RecordGUIDCOffset::~RecordGUIDCOffset() {}
1557 int RecordGUIDCOffset::handle_event()
1562 int RecordGUIDCOffset::keypress_event() { return 0; }
1564 RecordGUIDCOffsetText::RecordGUIDCOffsetText(char *text, int y, int number)
1565 : BC_TextBox(30, y+1, 67, 1, text, 0)
1567 this->number = number;
1570 RecordGUIDCOffsetText::~RecordGUIDCOffsetText()
1574 int RecordGUIDCOffsetText::handle_event()
1579 RecordGUIReset::RecordGUIReset(MWindow *mwindow, RecordGUI *gui, int y)
1580 : BC_Button(400, y, mwindow->theme->over_button)
1581 { this->gui = gui; }
1583 RecordGUIReset::~RecordGUIReset()
1587 int RecordGUIReset::handle_event()
1592 RecordGUIResetTranslation::RecordGUIResetTranslation(MWindow *mwindow, RecordGUI *gui, int y)
1593 : BC_Button(250, y, mwindow->theme->reset_data)
1598 RecordGUIResetTranslation::~RecordGUIResetTranslation()
1602 int RecordGUIResetTranslation::handle_event()
1604 gui->set_translation(0, 0, 1);