aboutsummaryrefslogtreecommitdiff
path: root/src/ui.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui.cc')
-rw-r--r--src/ui.cc115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/ui.cc b/src/ui.cc
new file mode 100644
index 0000000..3d0e193
--- /dev/null
+++ b/src/ui.cc
@@ -0,0 +1,115 @@
+#include "ui.h"
+#include "playback.h"
+#include "labeller.h"
+#include <opencv2/opencv.hpp>
+#include <iostream>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+namespace frontend {
+ struct ui_impl {
+ std::shared_ptr<playback> pb;
+ std::shared_ptr<backend::labeller> llr;
+ bool play = true;
+ bool stalePrintout = true;
+ };
+
+ ui::ui(std::shared_ptr<playback> playback, std::shared_ptr<backend::labeller> labeller) {
+ data = std::shared_ptr<ui_impl>(new ui_impl);
+ data->pb = playback;
+ data->llr = labeller;
+ }
+
+ bool handleKey(int keycode, const std::shared_ptr<ui_impl>& data) {
+ if(keycode != -1) {
+ data->stalePrintout = true;
+ if(keycode >= 48 && keycode <= 57) { // Number -> label
+ std::size_t num = keycode - 48;
+ if(num < data->llr->getLabels().size()) {
+ data->llr->applyLabel(data->llr->getLabels()[num], data->pb->getTime());
+ }
+ } else {
+ switch(keycode) {
+ case 27: // Escape quits
+ std::cout << std::endl;
+ return true;
+ case 32: // Space pauses
+ data->play = ! data->play;
+ break;
+ case 65361: // Left seeks backward 1 frame
+ data->pb->seekFrame(data->pb->getFrame() - 1);
+ break;
+ case 65362: // Up seeks backward 1 second
+ if(data->pb->getTime() < 1) {
+ data->pb->seekTime(data->pb->getTime() * -1);
+ } else {
+ data->pb->seekTime(data->pb->getTime() - 1);
+ }
+ break;
+ case 65363: // Right seeks forward 1 frame
+ data->pb->seekFrame(data->pb->getFrame() + 1);
+ break;
+ case 65364: // Down seeks forward 1 second
+ data->pb->seekTime(data->pb->getTime() + 1);
+ break;
+ case 117: // u undoes
+ data->llr->undo();
+ break;
+ case 114: // r redoes
+ data->llr->redo();
+ break;
+ case 65535: // DEL deletes
+ data->llr->deleteLabel(data->pb->getTime());
+ break;
+ case 115: // s saves
+ data->llr->save();
+ break;
+ default:
+ std::cout << "Pressed the " << keycode << " key" << std::endl;
+ break;
+ }
+ }
+ }
+ return false;
+ }
+
+ void ui::begin() {
+ std::cout << "Playing a video that's " << data->pb->getMaxFrame() << " frames (" << data->pb->getMaxTime() << " seconds) long." << std::endl;
+ std::cout << "Annotations:" << std::endl;
+ int num = 0;
+ for(auto ann : data->llr->getLabels()) {
+ std::cout << num++ << ": " << ann << std::endl;
+ }
+ // Get window size
+ struct winsize size;
+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
+ int cols = size.ws_col;
+ while(true) {
+ data->pb->display("Video");
+ data->pb->interFrameSleep();
+ if(handleKey(cv::pollKey(), data)) {
+ break;
+ }
+ if(data->play) {
+ data->pb->seekFrame(data->pb->getFrame() + 1);
+ }
+ if(data->play || data->stalePrintout) {
+ std::stringstream toPrint;
+ toPrint << "Frame: " << data->pb->getFrame() << " (" << std::setprecision(4) << std::setw(6) << std::left << data->pb->getTime() << " s)";
+ std::string timeString = toPrint.str();
+ toPrint.str(""); // clear contents
+ // Get surrounding labels
+ auto labs = data->llr->getSurrounding(data->pb->getTime());
+ if(! labs.first.name.empty()) toPrint << labs.first.name << " (t=" << std::setprecision(4) << labs.first.time << ")";
+ else toPrint << "START (t=0)";
+ toPrint << " CURRENT ";
+ if(! labs.second.name.empty()) toPrint << labs.second.name << " (t=" << std::setprecision(4) << labs.second.time << ")";
+ else toPrint << "END (t=" << data->pb->getMaxTime() << ")";
+ toPrint << std::string(cols - toPrint.str().size() - timeString.size() - 1, ' ') << timeString;
+ std::cout << "\r\b\r" << toPrint.str();
+ std::cout.flush();
+ data->stalePrintout = false;
+ }
+ }
+ }
+}