gaze  0.1.0
Perform gaze tracking with common webcams.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
debug_window.cpp
1 #include "gaze/gui/debug_window.h"
2 
3 #include <memory>
4 #include <sstream>
5 #include <thread> // NOLINT
6 #include <utility>
7 
8 #include "dlib/geometry.h"
9 #include "dlib/gui_core.h"
10 #include "dlib/gui_widgets.h"
11 #include "dlib/unicode.h"
12 
13 #include "gaze/gui/event_manager.h"
14 #include "gaze/gui/visualizeable.h"
15 #include "gaze/pipeline.h"
16 
17 
18 namespace gaze {
19 
20 namespace gui {
21 
23  : dlib::drawable_window(false, false),
24  pause_button(*this),
25  paused(false),
26  pipeline(pipeline),
27  pipeline_steps(pipeline->get_steps()),
28  pipeline_tabs(*this),
29  statistics_widget(*this) {
30  this->set_size(this->w_width, this->w_height);
31  this->set_title("GazeTracker DebugWindow");
32 
33  this->pause_button.set_pos(this->w_margin, this->w_margin);
34  this->pause_button.set_name("Pause");
35  this->pause_button.set_click_handler([this]() {
36  this->paused ^= true;
37  });
38 
39  this->statistics_widget.set_pos(
40  this->w_margin,
41  this->pause_button.bottom() + this->w_margin);
42  this->statistics_widget.set_size(
43  this->stat_width,
44  this->w_height - 3 * this->w_margin - this->pause_button.height());
45  this->statistics_widget.set_grid_size(this->pipeline_steps.size() + 1, 2);
46  this->statistics_widget.set_text(0, 0, "Pipeline step");
47  this->statistics_widget.set_text(0, 1,
48  dlib::convert_utf8_to_utf32("Execution time (\u00B5s)"));
49  for (auto row = decltype(this->statistics_widget.number_of_rows()){0};
50  row < this->statistics_widget.number_of_rows();
51  ++row) {
52  for (auto col = decltype(this->statistics_widget.number_of_columns()){0};
53  col < this->statistics_widget.number_of_columns();
54  ++col) {
55  this->statistics_widget.set_editable(row, col, false);
56  }
57  }
58 
59  this->pipeline_tabs.set_pos(this->statistics_widget.right() + this->w_margin,
60  this->pause_button.bottom() + this->w_margin);
61  this->pipeline_tabs.set_size(this->w_width - 3 * this->w_margin
62  - this->stat_width,
63  this->w_height - 3 * this->w_margin
64  - this->pause_button.height());
65  this->pipeline_tabs.set_number_of_tabs(
66  this->pipeline_steps.size() > 0 ? this->pipeline_steps.size() : 1);
67  this->pipeline_tabs.set_click_handler([this](auto new_idx, auto)
68  -> void {
69  this->process_data(new_idx);
70  });
71 
72  int width = this->pipeline_tabs.width() - 3 * this->w_margin;
73  int height = this->pipeline_tabs.height() - 3 * this->w_margin
74  - this->pause_button.height();
75  for (auto i = decltype(this->pipeline_steps.size()){0};
76  i < this->pipeline_steps.size(); ++i) {
78  if (VisualizeableBase* step =
79  dynamic_cast<VisualizeableBase*>(this->pipeline_steps[i])) {
80  widget = step->init(*this, width, height);
81  } else {
82  std::shared_ptr<dlib::label> tmp(new dlib::label(*this));
83  tmp->set_text("No visualization.");
84  widget = tmp;
85  }
86 
87  // Create widget group, add widget to it
88  std::shared_ptr<dlib::widget_group> widget_group_ptr(
89  new dlib::widget_group(*this));
90  this->widgets.push_back(widget_group_ptr);
91  widget_group_ptr->add(*widget.get(), this->w_margin, this->w_margin);
92 
93  // Assign name and add widget group to tab
94  this->pipeline_tabs.set_tab_name(i, this->pipeline_steps[i]->get_name());
95  this->pipeline_tabs.set_tab_group(i, *widget_group_ptr.get());
96 
97  // Assign name to statistics widget
98  this->statistics_widget.set_text(i + 1, 0,
99  this->pipeline_steps[i]->get_name());
100  }
101 
102  this->show();
103  if (this->pipeline_steps.size() > 0) {
105  }
106 }
107 
108 DebugWindow::~DebugWindow() {
110  for (PipelineStep* step : this->pipeline_steps) {
111  if (VisualizeableBase* vb = dynamic_cast<VisualizeableBase*>(step)) {
112  if (vb) {
113  vb->remove_widget();
114  }
115  }
116  }
117  this->close_window();
118 }
119 
121  idx = idx < 0 ? this->pipeline_tabs.selected_tab() : idx;
122 
123  if (this->pipeline_steps.size() == 0) {
124  return;
125  }
126 
127  if (VisualizeableBase* step =
128  dynamic_cast<VisualizeableBase*>(this->pipeline_steps[idx])) {
129  step->visualize(this->data);
130  }
131 
132  for (auto i = decltype(this->pipeline_steps.size()){1};
133  i <= this->pipeline_steps.size(); ++i) {
135  os << this->data.execution_times[this->pipeline_steps[i - 1]->get_name()];
136  this->statistics_widget.set_text(i, 1, os.str());
137  }
138 }
139 
140 void DebugWindow::on_user_event(void*, int event_type) {
141  switch (event_type) {
142  case Events::PIPELINE_DATA_UPDATED:
143  if (this->paused) {
144  break;
145  }
146  this->data = this->pipeline->get_data();
147  this->process_data();
148  break;
149  }
150 }
151 
152 namespace {
153 
160 void _open_debug_window(Pipeline* pipeline) {
161  DebugWindow(pipeline).wait_until_closed();
162 }
163 
164 } // namespace
165 
166 void open_debug_window(Pipeline* pipeline) {
167  std::thread(&_open_debug_window, pipeline).detach();
168 }
169 
170 } // namespace gui
171 
172 } // namespace gaze
static EventManager & instance()
DebugWindow(Pipeline *pipeline)
Abstract base class for PipelineSteps. Must be inherited from.
Definition: pipeline_step.h:18
Abstract base class for Visualizeable to allow generic pointers.
The processing pipeline from input to output.
Definition: pipeline.h:19
void process_data(int idx=-1)
void unsubscribe(dlib::base_window *subscriber)
util::Data get_data()
Definition: pipeline.cpp:69
A window to inspect computation results.
Definition: debug_window.h:22
void push_back(const value_type &__x)
std::map< std::string, double > execution_times
Definition: data.h:111
void on_user_event(void *event_data, int event_type) override
__string_type str() const
void subscribe(dlib::base_window *subscriber)