Skip to content
Snippets Groups Projects
Commit b74a4cea authored by Iiro Rastas's avatar Iiro Rastas
Browse files

Fix recording window functionality

- The file extension is now chosen based on the chosen recording type.
- The record button is disabled while the recording window is open,
preventing the user from attempting to start multiple recordings
simultaneously.
- The color of the record button is now also changed to red when the
recording is started from the recording window.
- The available channels are now set as the recording window is opened.
parent 8da8f85b
No related branches found
No related tags found
1 merge request!194Recording enhancements
Pipeline #16837 passed
......@@ -37,69 +37,70 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen, ftl::gui::SourceWindow *sourceW
virtualCameraRecording_ = std::optional<ftl::gui::Camera*>();
sceneRecording_ = std::optional<ftl::Configurable*>();
auto recordbutton = new PopupButton(this, "", ENTYPO_ICON_CONTROLLER_RECORD);
recordbutton->setTooltip("Record");
recordbutton->setSide(Popup::Side::Right);
recordbutton->setChevronIcon(0);
auto recordpopup = recordbutton->popup();
recordbutton_ = new PopupButton(this, "", ENTYPO_ICON_CONTROLLER_RECORD);
recordbutton_->setTooltip("Record");
recordbutton_->setSide(Popup::Side::Right);
recordbutton_->setChevronIcon(0);
auto recordpopup = recordbutton_->popup();
recordpopup->setLayout(new GroupLayout());
recordpopup->setTheme(screen->toolbuttheme);
recordpopup->setAnchorHeight(150);
auto itembutton = new Button(recordpopup, "2D snapshot (.png)");
itembutton->setCallback([this,recordbutton]() {
itembutton->setCallback([this]() {
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
screen_->activeCamera()->snapshot(std::string(timestamp) + ".png");
recordbutton->setPushed(false);
recordbutton_->setPushed(false);
});
itembutton = new Button(recordpopup, "Virtual camera recording (.ftl)");
itembutton->setCallback([this,recordbutton]() {
itembutton->setCallback([this]() {
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
auto filename = std::string(timestamp) + ".ftl";
toggleVirtualCameraRecording(screen_->activeCamera(), filename);
recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
recordbutton->setPushed(false);
startRecording2D(screen_->activeCamera(), filename);
recordbutton_->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
recordbutton_->setPushed(false);
});
itembutton = new Button(recordpopup, "3D scene snapshot (.ftl)");
itembutton->setCallback([this,recordbutton]() {
itembutton->setCallback([this]() {
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
snapshot3D(screen_->activeCamera(), std::string(timestamp) + ".ftl");
recordbutton->setPushed(false);
recordbutton_->setPushed(false);
});
itembutton = new Button(recordpopup, "3D scene recording (.ftl)");
itembutton->setCallback([this,recordbutton]() {
itembutton->setCallback([this]() {
char timestamp[18];
std::time_t t=std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
startRecording3D(screen_->activeCamera(), std::string(timestamp) + ".ftl");
recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
recordbutton->setPushed(false);
recordbutton_->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
recordbutton_->setPushed(false);
});
itembutton = new Button(recordpopup, "Detailed recording options");
itembutton->setCallback([this,sourceWindow,recordbutton] {
itembutton->setCallback([this,sourceWindow] {
auto record_window = new RecordWindow(screen_, screen_, sourceWindow->getCameras(), this);
record_window->setTheme(screen_->windowtheme);
recordbutton->setPushed(false);
recordbutton_->setPushed(false);
recordbutton_->setEnabled(false);
});
recordbutton->setCallback([this,recordbutton](){
recordbutton_->setCallback([this](){
if (virtualCameraRecording_) {
virtualCameraRecording_.value()->stopVideoRecording();
recordbutton->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
recordbutton_->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
// Prevents the popup from being opened, though it is shown while the button
// is being pressed.
recordbutton->setPushed(false);
recordbutton_->setPushed(false);
virtualCameraRecording_ = std::nullopt;
} else if (sceneRecording_) {
sceneRecording_.value()->set("record", false);
recordbutton->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
recordbutton->setPushed(false);
recordbutton_->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
recordbutton_->setPushed(false);
sceneRecording_ = std::nullopt;
}
});
......@@ -294,9 +295,10 @@ void MediaPanel::cameraChanged() {
}
}
void MediaPanel::toggleVirtualCameraRecording(ftl::gui::Camera *camera, const std::string &filename) {
void MediaPanel::startRecording2D(ftl::gui::Camera *camera, const std::string &filename) {
camera->startVideoRecording(filename);
virtualCameraRecording_ = std::optional<ftl::gui::Camera*>(camera);
recordbutton_->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
}
void MediaPanel::snapshot3D(ftl::gui::Camera *camera, const std::string &filename) {
......@@ -321,6 +323,11 @@ void MediaPanel::startRecording3D(ftl::gui::Camera *camera, const std::string &f
configurable->set("record-name", filename);
configurable->set("record", true);
sceneRecording_ = std::optional<ftl::Configurable*>(configurable);
recordbutton_->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
}
}
}
void MediaPanel::recordWindowClosed() {
recordbutton_->setEnabled(true);
}
\ No newline at end of file
......@@ -24,12 +24,14 @@ class MediaPanel : public nanogui::Window {
void cameraChanged();
void toggleVirtualCameraRecording(ftl::gui::Camera *camera, const std::string &filename);
void startRecording2D(ftl::gui::Camera *camera, const std::string &filename);
void snapshot3D(ftl::gui::Camera *camera, const std::string &filename);
void startRecording3D(ftl::gui::Camera *camera, const std::string &filename);
void recordWindowClosed();
private:
ftl::gui::Screen *screen_;
......@@ -40,6 +42,7 @@ class MediaPanel : public nanogui::Window {
nanogui::PopupButton *button_channels_;
nanogui::Button *right_button_;
nanogui::Button *depth_button_;
nanogui::PopupButton *recordbutton_;
/**
* These members indicate which type of recording is active, if any.
......
......@@ -23,17 +23,23 @@ RecordWindow::RecordWindow(nanogui::Widget *parent, ftl::gui::Screen *screen, co
char timestamp[18];
std::time_t t = std::time(NULL);
std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
// TODO: Change the file type specifier to be set based on the type of the recording.
auto fileName = new TextBox(this, std::string(timestamp) + ".ftl");
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;
for (const auto s : streams) {
if (s == screen->activeCamera()) {
ix = std::optional<int>(streamNames.size());
}
streamNames.push_back(s->source()->getURI());
}
auto streamSelect = new ComboBox(this, streamNames);
// TODO: Set the default stream to be the active stream if there is one.
// TODO: The function availableChannels() only finds those channels that
// have been set in camera.cpp. The only channels that are set in
// camera.cpp currently are Colour and Depth. This means that currently,
......@@ -51,11 +57,20 @@ RecordWindow::RecordWindow(nanogui::Widget *parent, ftl::gui::Screen *screen, co
snapshot3D->setLayout(new GroupLayout());
recording3D->setLayout(new GroupLayout());
new Label(snapshot2D, "Select channel (in addition to Left)", "sans-bold");
auto snapshotChannel = snapshot2D->add<ComboBox>();
// 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>();
streamSelect->setCallback([this,streams,snapshotChannel,recordingChannel](int ix) {
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();
......@@ -63,39 +78,44 @@ RecordWindow::RecordWindow(nanogui::Widget *parent, ftl::gui::Screen *screen, co
channels_.push_back(c);
channel_names_.push_back(ftl::codecs::name(c));
}
snapshotChannel->setItems(channel_names_);
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,tabWidget,snapshot2D,recording2D,snapshot3D,recording3D,snapshotChannel,recordingChannel]() {
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) {
// If the channel isn't the same as the one that was active
// previously, the channel won't have an image.
// One possible solution is to set the channels immediately
// as they are chosen in the recording window.
// Alternatively, 2D snapshots might not need a channel option at all.
stream->setChannel(channels_[snapshotChannel->selectedIndex()]);
stream->snapshot(fileName->value());
stream->snapshot(name);
} else if (tab == recording2D) {
stream->setChannel(channels_[recordingChannel->selectedIndex()]);
screen->setActiveCamera(stream);
media_panel->toggleVirtualCameraRecording(stream, fileName->value());
media_panel->startRecording2D(stream, name);
} else if (tab == snapshot3D) {
media_panel->snapshot3D(stream, fileName->value());
media_panel->snapshot3D(stream, name);
} else if (tab == recording3D) {
media_panel->startRecording3D(stream, fileName->value());
media_panel->startRecording3D(stream, name);
}
dispose();
media_panel->recordWindowClosed();
});
button = new Button(actionButtons, "Cancel");
button->setCallback([this]() {
button->setCallback([this,media_panel]() {
dispose();
media_panel->recordWindowClosed();
});
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment