From d3e66259bd57096e4afa82144afe40005ba1d75b Mon Sep 17 00:00:00 2001
From: Iiro Rastas <iitara@utu.fi>
Date: Mon, 11 Nov 2019 15:53:52 +0200
Subject: [PATCH] Add snapshot feature and fix settings window

The GUI now has a snapshot feature. The record button opens a popup
window, which contains the different recording options.

The cog icon now opens a scrollable list of all of the registered
configurations, both local and remote. This window is created
dynamically each time the cog icon is clicked, so it now includes all of the
configurations that were available as the window was created.
---
 applications/gui/src/camera.cpp        | 10 ++++++++++
 applications/gui/src/camera.hpp        |  2 ++
 applications/gui/src/config_window.cpp |  8 +++++++-
 applications/gui/src/media_panel.cpp   | 25 ++++++++++++++++++++-----
 applications/gui/src/screen.cpp        | 23 ++++++++++++-----------
 5 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp
index debb8e73d..b9812d95e 100644
--- a/applications/gui/src/camera.cpp
+++ b/applications/gui/src/camera.cpp
@@ -493,6 +493,16 @@ const GLTexture &ftl::gui::Camera::captureFrame() {
 	return texture1_;
 }
 
+void ftl::gui::Camera::snapshot() {
+	UNIQUE_LOCK(mutex_, lk);
+	char timestamp[18];
+	std::time_t t = std::time(NULL);
+	std::strftime(timestamp, sizeof(timestamp), "%F-%H%M%S", std::localtime(&t));
+	cv::Mat image;
+	cv::flip(im1_, image, 0);
+	cv::imwrite(std::string(timestamp) + ".png", image);
+}
+
 nlohmann::json ftl::gui::Camera::getMetaData() {
 	return nlohmann::json();
 }
diff --git a/applications/gui/src/camera.hpp b/applications/gui/src/camera.hpp
index 24dcbacfd..cc874305c 100644
--- a/applications/gui/src/camera.hpp
+++ b/applications/gui/src/camera.hpp
@@ -51,6 +51,8 @@ class Camera {
 
 	bool thumbnail(cv::Mat &thumb);
 
+	void snapshot();
+
 	nlohmann::json getMetaData();
 
 	StatisticsImage *stats_ = nullptr;
diff --git a/applications/gui/src/config_window.cpp b/applications/gui/src/config_window.cpp
index d75772f09..6112fe822 100644
--- a/applications/gui/src/config_window.cpp
+++ b/applications/gui/src/config_window.cpp
@@ -6,6 +6,7 @@
 #include <nanogui/button.h>
 #include <nanogui/entypo.h>
 #include <nanogui/formhelper.h>
+#include <nanogui/vscrollpanel.h>
 
 #include <vector>
 #include <string>
@@ -27,8 +28,13 @@ ConfigWindow::ConfigWindow(nanogui::Widget *parent, ftl::ctrl::Master *ctrl)
 
 	new Label(this, "Select Configurable","sans-bold");
 
+	auto vscroll = new VScrollPanel(this);
+	vscroll->setFixedHeight(300);
+	Widget *buttons = new Widget(vscroll);
+	buttons->setLayout(new BoxLayout(Orientation::Vertical, Alignment::Fill));
+
 	for (auto c : configurables_) {
-		auto itembutton = new Button(this, c);
+		auto itembutton = new Button(buttons, c);
 		itembutton->setCallback([this,c]() {
 			LOG(INFO) << "Change configurable: " << c;
 			_buildForm(c);
diff --git a/applications/gui/src/media_panel.cpp b/applications/gui/src/media_panel.cpp
index 407fb9172..639b1c50d 100644
--- a/applications/gui/src/media_panel.cpp
+++ b/applications/gui/src/media_panel.cpp
@@ -34,9 +34,22 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen) : nanogui::Window(screen, ""),
 		if (cam) cam->showPoseWindow();
 	});
 
-	button = new Button(this, "", ENTYPO_ICON_CONTROLLER_RECORD);
-	button->setFlags(Button::ToggleButton);
-	button->setChangeCallback([this,button](bool state) {
+	auto 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, "Snapshot");
+	itembutton->setCallback([this](){
+		screen_->activeCamera()->snapshot();
+	});
+	itembutton = new Button(recordpopup, "2D video recording");
+	itembutton = new Button(recordpopup, "Depth video recording");
+	itembutton->setFlags(Button::ToggleButton);
+	itembutton->setChangeCallback([this,recordbutton](bool state) {
 		auto tag = screen_->activeCamera()->source()->get<std::string>("uri");
 		if (tag) {
 			auto tagvalue = tag.value();
@@ -45,14 +58,16 @@ MediaPanel::MediaPanel(ftl::gui::Screen *screen) : nanogui::Window(screen, ""),
 				ftl::Configurable *configurable = configurables[0];
 				if (state){
 					configurable->set("record", true);
-					button->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
+					recordbutton->setTextColor(nanogui::Color(1.0f,0.1f,0.1f,1.0f));
 				} else {
-					button->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
+					recordbutton->setTextColor(nanogui::Color(1.0f,1.0f,1.0f,1.0f));
 					configurable->set("record", false);
 				}
 			}
 		}
 	});
+	itembutton = new Button(recordpopup, "3D scene recording");
+	itembutton = new Button(recordpopup, "Detailed recording options");
 
 	button = new Button(this, "", ENTYPO_ICON_CONTROLLER_STOP);
 	button->setCallback([this]() {
diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp
index 474952f0c..eb3650f3f 100644
--- a/applications/gui/src/screen.cpp
+++ b/applications/gui/src/screen.cpp
@@ -213,18 +213,18 @@ ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl
 		popup->setVisible(false);
 	});
 
-	popbutton = new PopupButton(innertool, "", ENTYPO_ICON_COG);
-	popbutton->setIconExtraScale(1.5f);
-	popbutton->setTheme(toolbuttheme);
-	popbutton->setTooltip("Settings");
-	popbutton->setFixedSize(Vector2i(40,40));
-	popbutton->setSide(Popup::Side::Right);
-	popbutton->setChevronIcon(0);
-	// popbutton->setPosition(Vector2i(5,height()-50));
-	popup = popbutton->popup();
-	popup->setLayout(new GroupLayout());
-	popup->setTheme(toolbuttheme);
+	itembutton = new Button(innertool, "", ENTYPO_ICON_COG);
+	itembutton->setIconExtraScale(1.5f);
+	itembutton->setTheme(toolbuttheme);
+	itembutton->setTooltip("Settings");
+	itembutton->setFixedSize(Vector2i(40,40));
+
+	itembutton->setCallback([this]() {
+		auto config_window = new ConfigWindow(this, ctrl_);
+		config_window->setTheme(windowtheme);
+	});
 
+	/*
 	//net_->onConnect([this,popup](ftl::net::Peer *p) {
 	{
 		LOG(INFO) << "NET CONNECT";
@@ -247,6 +247,7 @@ ftl::gui::Screen::Screen(ftl::Configurable *proot, ftl::net::Universe *pnet, ftl
 		auto config_window = new ConfigWindow(this, ctrl_);
 		config_window->setTheme(windowtheme);
 	});
+	*/
 
 	//configwindow_ = new ConfigWindow(parent, ctrl_);
 	cwindow_ = new ftl::gui::ControlWindow(this, controller);
-- 
GitLab