se2ez
mainwindow.cpp
Go to the documentation of this file.
1 /* Author: Constantinos Chamzas, Zachary Kingston */
2 
3 #include <iostream>
4 #include <chrono>
5 
6 #include <QTimer>
7 
8 #include <se2ez/core/log.h>
9 #include <se2ez/core/io.h>
10 #include <se2ez/core/robot.h>
11 #include <se2ez/core/state.h>
12 #include <se2ez/core/joint.h>
13 
14 #include <se2ez/gui/panel.h>
15 #include <se2ez/gui/renderarea.h>
16 #include <se2ez/gui/mainwindow.h>
17 
18 #include "ui_mainwindow.h"
19 
20 using namespace se2ez;
21 
22 // TODO make renderArea accept mainWindow as parent and use that
24  : QMainWindow(parent), ui_(new Ui::MainWindow), panels_(std::make_shared<PanelMap>())
25 {
26  ui_->setupUi(this);
27  canvas_ = new gui::RenderArea(this, this);
28 
29  ui_->vbox->insertWidget(0, canvas_);
30 
31  connect(ui_->xSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateOriginX(double)));
32  connect(ui_->ySpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateOriginY(double)));
33  connect(ui_->zoomSpinBox, SIGNAL(valueChanged(double)), this, SLOT(updateScale(double)));
34  connect(ui_->grid, SIGNAL(stateChanged(int)), this, SLOT(updateState()));
35 
36  connect(ui_->record, SIGNAL(clicked()), this, SLOT(record()));
37  connect(ui_->screenshot, SIGNAL(clicked()), this, SLOT(screenshot()));
38 
39  QTimer::singleShot(1. / ui_->fps->value() * 1000, this, SLOT(process()));
40  last_ = io::getDate();
41 }
42 
44 {
45  auto now = io::getDate();
46  for (const auto &panel : *panels_)
47  panel.second->update(last_, now);
48 
50 
51  if (!canvas_->didPaint() && didUpdate_)
52  canvas_->paint(true);
53 
54  if (update_)
55  canvas_->paint();
56 
58 
59  if (screen_)
60  {
61  const std::string name = log::format("./screen_%1%.png", now);
62  canvas_->takeScreenshot(name);
63 
64  SE2EZ_INFORM("Screenshot saved to %1%", io::resolvePath(name));
65  screen_ = false;
66  }
67 
68  if (record_)
69  canvas_->takeScreenshot(log::format("%1%/%2$08d.png", directory_, shotnum_++));
70 
71  update_ = false;
72  last_ = now;
73 
75  QTimer::singleShot(1. / ui_->fps->value() * 1000, this, SLOT(process()));
76 }
77 
79 {
80  if (camera_)
81  {
82  camera_->join();
83  delete camera_;
84  }
85 
86  delete ui_;
87 }
88 
89 void gui::MainWindow::resizeEvent(QResizeEvent *e)
90 {
92  QWidget::resizeEvent(e);
93 }
94 
96 {
97  ui_->tabWidget->addTab(panel, panel->name);
98  panels_->emplace(panel->name.toStdString(), panel);
99  // Register the shared panelMap for this panel
100  panel->initialize(panels_);
101 
102  connect(panel, SIGNAL(stateChanged()), this, SLOT(updateState()));
103 }
104 
106 {
108  update_ = true;
109 }
110 
112 {
114  canvas_->setOriginX(x);
115 
116  update_ = true;
117 }
118 
120 {
122  canvas_->setOriginY(y);
123 
124  update_ = true;
125 }
127 {
129  canvas_->setScale(scale);
130 
131  update_ = true;
132 }
133 
134 void gui::MainWindow::draw(QPainter &painter, RenderArea *canvas)
135 {
136  for (int i = ui_->tabWidget->count() - 1; i >= 0; --i)
137  {
138  const std::string &name = ui_->tabWidget->tabText(i).toStdString();
139  panels_->find(name)->second->draw(painter, canvas);
140  }
141 }
142 
143 void gui::MainWindow::click(QMouseEvent *event, double x, double y, int sx, int sy)
144 {
145  const std::string &name = ui_->tabWidget->tabText(ui_->tabWidget->currentIndex()).toUtf8().constData();
146  auto it = panels_->find(name);
147  if (it != panels_->end() && it->second->click(event, x, y, sx, sy))
148  return;
149 
150  for (int i = 0; i < ui_->tabWidget->count(); ++i)
151  {
152  const std::string &name = ui_->tabWidget->tabText(i).toUtf8().constData();
153 
154  auto it = panels_->find(name);
155  if (it != panels_->end() && it->second->click(event, x, y, sx, sy))
156  return;
157  }
158 
159 }
160 
162 {
163  if (!record_)
164  {
165  ui_->record->setText(QString("Recording..."));
166  ui_->record->setDown(true);
167 
168  record_ = true;
169  directory_ = log::format("./record_%1%", io::getDate());
171 
172  SE2EZ_INFORM("Recording to %1%...", directory_);
173 
174  shotnum_ = 0;
175  }
176  else
177  {
178  record_ = false;
179  ui_->record->setText(QString("Record"));
180  ui_->record->setDown(false);
181 
182  SE2EZ_INFORM("Recorded %1% frames. Compiling video...", shotnum_ + 1);
183 
184  if (camera_)
185  {
186  camera_->join();
187  delete camera_;
188  }
189 
190  camera_ = new std::thread([&]() {
191  io::runCommand( //
192  log::format("ffmpeg -framerate %2% -i \"%1%/%%08d.png\" "
193  "-pix_fmt rgb24 -c:v qtrle \"%1%/%1%.mov\"", //
194  directory_, ui_->fps->value() / 2));
195 
196  io::runCommand( //
197  log::format("ffmpeg -i \"%1%/%1%.mov\" -c:v libx264 -preset slow -crf 22 \"%1%/%1%.mkv\"",
198  directory_));
199 
200  SE2EZ_INFORM("Video compiled to %1%/%1%.{mov,mkv}", directory_);
201  });
202  }
203 }
204 
206 {
207  screen_ = true;
208 }
void updateScale(double scale)
Slot called when the scale is updated.
Definition: mainwindow.cpp:126
T unlock(T... args)
void createDirectory(const std::string &dir)
Creates a directory.
Definition: io.cpp:157
The main widget that acts a container for other widgets (canvas, panels). It also delegates the drawi...
Definition: mainwindow.h:34
boost::posix_time::ptime last_
Definition: mainwindow.h:116
Definition: cspacepanel.h:22
RenderArea * canvas_
The canvas widget.
Definition: mainwindow.h:102
~MainWindow()
Destructor Nothing intresting for now.
Definition: mainwindow.cpp:78
void setOriginY(double y)
Definition: renderarea.cpp:169
void setScale(double scale)
Definition: renderarea.cpp:179
void addPanel(Panel *panel)
Adds a panel to the main GUI.
Definition: mainwindow.cpp:95
MainWindow(QWidget *parent=nullptr)
Constructor. Nothing intresting for now.
Definition: mainwindow.cpp:23
#define SE2EZ_INFORM(fmt,...)
Definition: log.h:43
void updateOriginY(double y)
Slot called when the origin is updated.
Definition: mainwindow.cpp:119
T join(T... args)
void draw(QPainter &painter, RenderArea *canvas)
Asks all the panels to draw their respective information.
Definition: mainwindow.cpp:134
void takeScreenshot(const std::string &file)
Definition: renderarea.cpp:500
T lock(T... args)
Ui::MainWindow * ui_
UI (User Interface) pointer.
Definition: mainwindow.h:101
void updateOriginX(double x)
Slot called when the origin is updated.
Definition: mainwindow.cpp:111
boost::posix_time::ptime getDate()
Get the current time (up to milliseconds)
Definition: io.cpp:195
unsigned int shotnum_
Number of screenshots taken.
Definition: mainwindow.h:110
QString name
Definition: panel.h:45
void setOriginX(double x)
Definition: renderarea.cpp:159
std::string format(const std::string &fmt, Args &&... args)
Definition: log.h:25
void updateState()
calls the update function from canvas to draw the updated state
Definition: mainwindow.cpp:105
void paint(bool force=false)
Definition: renderarea.cpp:348
void resizeEvent(QResizeEvent *e) override
Definition: mainwindow.cpp:89
The canvas widget. It contains all the drawing functions as well as all the general settings for draw...
Definition: renderarea.h:48
Main namespace.
Definition: collision.h:11
const std::string runCommand(const std::string &cmd)
Runs a command cmd and returns stdout as a string.
Definition: io.cpp:106
std::thread * camera_
Thread used to record the camera.
Definition: mainwindow.h:107
const std::string resolvePath(const std::string &path)
Resolves file paths to their canonical form.
Definition: io.cpp:79
virtual void initialize(MainWindow::PanelMapPtr p)
Definition: panel.h:40
std::mutex updateMutex_
Definition: mainwindow.h:114
void click(QMouseEvent *event, double x, double y, int sx, int sy)
Asks the top panel to click at the location.
Definition: mainwindow.cpp:143
PanelMapPtr panels_
Holds the panels.
Definition: mainwindow.h:103
std::string directory_
Directory to save screenshots/videos.
Definition: mainwindow.h:108