#include "record_window.hpp" #include "screen.hpp" #include <ftl/codecs/channels.hpp> #include <nanogui/layout.h> #include <nanogui/button.h> #include <nanogui/combobox.h> #include <nanogui/label.h> #include <nanogui/textbox.h> #include <nanogui/tabwidget.h> using ftl::gui::RecordWindow; RecordWindow::RecordWindow(nanogui::Widget *parent, ftl::gui::Screen *screen, const std::vector<ftl::gui::Camera *> &streams, ftl::gui::MediaPanel *media_panel) : nanogui::Window(parent, "Recording options") { using namespace nanogui; setLayout(new GroupLayout()); new Label(this, "File name", "sans-bold"); char timestamp[18]; std::time_t t = std::time(NULL); std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t)); Widget *fileNameBox = new Widget(this); fileNameBox->setLayout(new BoxLayout(Orientation::Horizontal, Alignment::Middle, 0, 6)); auto fileName = new TextBox(fileNameBox, std::string(timestamp)); fileName->setFixedWidth(350); fileName->setEditable(true); auto extension = new Label(fileNameBox, ".png", "sans-bold"); new Label(this, "Select stream", "sans-bold"); auto streamNames = std::vector<std::string>(); streamNames.reserve(streams.size()); std::optional<int> ix; int i=1; for (const auto s : streams) { if (s == screen->activeCamera()) { ix = std::optional<int>(streamNames.size()); } streamNames.push_back(std::string("Stream")+std::to_string(i++)); } auto streamSelect = new ComboBox(this, streamNames); TabWidget *tabWidget = add<TabWidget>(); tabWidget->setFixedWidth(400); auto snapshot2D = tabWidget->createTab("2D snapshot"); auto recording2D = tabWidget->createTab("2D recording"); auto snapshot3D = tabWidget->createTab("3D snapshot"); auto recording3D = tabWidget->createTab("3D recording"); snapshot2D->setLayout(new GroupLayout()); recording2D->setLayout(new GroupLayout()); snapshot3D->setLayout(new GroupLayout()); recording3D->setLayout(new GroupLayout()); // Set the file name extension based on the type of recording chosen. tabWidget->setCallback([tabWidget,snapshot2D,extension](int ix) { if (tabWidget->tab(ix) == snapshot2D) { extension->setCaption(".png"); } else { extension->setCaption(".ftl"); } }); tabWidget->setActiveTab(0); new Label(recording2D, "Select channel (in addition to Left)", "sans-bold"); auto recordingChannel = recording2D->add<ComboBox>(); auto streamCallback = [this,streams,recordingChannel](int ix) { channels_ = std::vector<ftl::codecs::Channel>(); channel_names_ = std::vector<std::string>(); ftl::codecs::Channels availableChannels = streams[ix]->availableChannels(); for (auto c : availableChannels) { channels_.push_back(c); channel_names_.push_back(ftl::codecs::name(c)); } recordingChannel->setItems(channel_names_); }; streamSelect->setCallback(streamCallback); // Set the selection to the active stream and set the channel list // to be the channels available in that stream. The callback must // be called explicitly, since setSelectedIndex() does not trigger it. if (ix) { streamSelect->setSelectedIndex(ix.value()); streamCallback(ix.value()); } Widget *actionButtons = new Widget(this); actionButtons->setLayout(new BoxLayout(Orientation::Horizontal)); auto button = new Button(actionButtons, "Start"); button->setCallback([this,streams,streamSelect,screen,media_panel,fileName,extension,tabWidget,snapshot2D,recording2D,snapshot3D,recording3D,recordingChannel]() { // Check the chosen stream type and channels, then record them. std::string name = fileName->value() + extension->caption(); auto stream = streams[streamSelect->selectedIndex()]; auto tab = tabWidget->tab(tabWidget->activeTab()); if (tab == snapshot2D) { stream->snapshot(name); } else if (tab == recording2D) { stream->setChannel(channels_[recordingChannel->selectedIndex()]); screen->setActiveCamera(stream); //media_panel->startRecording2D(stream, name); } else if (tab == snapshot3D) { //media_panel->snapshot3D(stream, name); } else if (tab == recording3D) { //media_panel->startRecording3D(stream, name); } dispose(); media_panel->recordWindowClosed(); }); button = new Button(actionButtons, "Cancel"); button->setCallback([this,media_panel]() { dispose(); media_panel->recordWindowClosed(); }); } RecordWindow::~RecordWindow() { }