CEBL  2.1
TabMonitor.cpp
Go to the documentation of this file.
1 
7 #include "TabMonitor.hpp"
8 #include "DataSourceCombo.hpp"
9 #include "WidgetUtils.hpp"
10 #include "EEGMonitor.hpp"
11 
12 //----------------------------------------------------------------------
13 // Constructors / Destructor
14 
16 {
17  if(plot!=NULL)
18  delete plot;
19 }
20 
21 
22 //----------------------------------------------------------------------
23 // Create the GUI
24 
25 
27 {
28  //add title
29  GtkWidget *title = gtk_label_new("");
30  gtk_label_set_markup(GTK_LABEL(title),"<big>Monitor</big>");
31  TabAdd(title);
32  TabAdd(gtk_hseparator_new());
33 
34 
35 
36  //set some member variables
37  this->collecting_data = false;
38  this->continue_plotting = false;
39  this->passive_plot = false;
40 
41  //boxes
42  GtkWidget * btn_box1 = gtk_hbutton_box_new();
43  gtk_button_box_set_layout(GTK_BUTTON_BOX(btn_box1),GTK_BUTTONBOX_START);
44  GtkWidget * btn_box2 = gtk_hbutton_box_new();
45  gtk_button_box_set_layout(GTK_BUTTON_BOX(btn_box2),GTK_BUTTONBOX_START);
46  GtkWidget *label_box = gtk_hbox_new(false,0);
47 
48  //create buttons
49  btn_start = gtk_button_new_with_label("Start Monitoring");
50  gtk_widget_set_size_request(btn_start,30,20);
51  g_signal_connect(G_OBJECT(btn_start),
52  "clicked",
53  G_CALLBACK(CB_StartMonitor),
54  (gpointer) this);
55 
56  btn_stop = gtk_button_new_with_label("Stop");
57  gtk_widget_set_sensitive(btn_stop,false);
58  g_signal_connect(G_OBJECT(btn_stop),
59  "clicked",
60  G_CALLBACK(CB_StopMonitor),
61  (gpointer) this);
62 
63  btn_start_collecting = gtk_button_new_with_label("Start Collecting");
64  g_signal_connect(G_OBJECT(btn_start_collecting),
65  "clicked",
66  G_CALLBACK(CB_StartCollect),
67  (gpointer) this);
68 
69 
70  check_filter = gtk_check_button_new_with_label("Enable Filter");
71  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_filter),false);
72  g_signal_connect(G_OBJECT(check_filter),
73  "toggled",
74  G_CALLBACK(CB_toggleFilter),
75  (gpointer) this);
76 
77 
78  GtkWidget *samples_label = gtk_label_new("Samples Collected: ");
79  label_collected_samples = gtk_label_new("0");
80 
81 
82  gtk_box_pack_start(GTK_BOX(btn_box1),btn_start,false,false,2);
83  gtk_box_pack_start(GTK_BOX(btn_box1),btn_start_collecting,false,false,2);
84  gtk_box_pack_start(GTK_BOX(btn_box1),gtk_label_new("Data Source: "), false, false, 2);
85  gtk_box_pack_start(GTK_BOX(btn_box1),getView()->getDataSource()->getCombo(),false,false,2);
86  gtk_box_pack_start(GTK_BOX(btn_box2),btn_stop,false,false,2);
87  gtk_box_pack_start(GTK_BOX(btn_box2),check_filter,false,false,2);
88  gtk_box_pack_start(GTK_BOX(label_box),samples_label,false,false,2);
89  gtk_box_pack_start(GTK_BOX(label_box),label_collected_samples,false,false,2);
90 
91  //pack button box into tab container
92  GtkWidget * btn_boxes = gtk_vbox_new(false,0);
93  gtk_box_pack_start(GTK_BOX(btn_boxes), btn_box1, false, false, 0);
94  gtk_box_pack_start(GTK_BOX(btn_boxes), btn_box2, false, false, 0);
95  TabFrameAdd(btn_boxes);
96 
97  TabAdd(label_box);
98 
99  //plot
100  plot = NULL;
101 }
102 
103 
104 
105 //----------------------------------------------------------------------
106 // EVENT GUI UPDATES
107 
110 {
111  this->updating_view = true;
112  // change button sensitivity based on stat of collection
113  if(this->continue_plotting)
114  {
115  if(this->collecting_data)
116  {
117  gtk_widget_set_sensitive(btn_start,false);
118  gtk_widget_set_sensitive(btn_stop,true);
119  gtk_widget_set_sensitive(btn_start_collecting,false);
120  }
121  else
122  {
123  gtk_widget_set_sensitive(btn_start,false);
124  gtk_widget_set_sensitive(btn_stop,true);
125  gtk_widget_set_sensitive(btn_start_collecting,false);
126  }
127  }
128  else
129  {
130  gtk_widget_set_sensitive(btn_start,true);
131  gtk_widget_set_sensitive(btn_stop,false);
132  gtk_widget_set_sensitive(btn_start_collecting,true);
133  }
134 
135  int num_samples = getView()->getModel()->dataGetStoreNumSamples();
136  gtk_label_set_text(GTK_LABEL(label_collected_samples),
137  TextUtils::IntToString(num_samples).c_str());
138 
140  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_filter),filter);
141 
142  this->updating_view = false;
143 }
144 
145 
146 //update the model from the widgets
148 {
149 
150 }
151 
154 {
155 
156  if(continue_plotting && plot->isDetached())
157  {
158  this->passive_plot = true;
159  getView()->getModel()->dataSetStoreFlag(true);
160  this->collecting_data = false;
161  this->collecting_data = false;
162  getView()->getModel()->dataStop();
163  getView()->getStatusBar()->remove(status_id);
164  updateView();
165  }
166  else
167  {
168  stopPlotting();
169  }
170 }
171 
172 
173 //----------------------------------------------------------------------
174 // PLOTTING
175 
177 void TabMonitor::createPlot()
178 {
179  if(plot==NULL)
180  {
181  plot = new EEGMonitor(this,this->getView()->getModel()->channelsGetNumEnabledChannels());
182  plot->setLabels(this->getView()->getModel()->channelsGetEnabledNames());
183  plot->reInitPlot(this->getView()->getModel()->channelsGetNumEnabledChannels());
184  TabAdd(*plot, true, true, 0);
185  }
186  else
187  {
188  plot->setLabels(this->getView()->getModel()->channelsGetEnabledNames());
189  plot->reInitPlot(this->getView()->getModel()->channelsGetNumEnabledChannels());
190 
191  }
192 }
193 
194 bool TabMonitor::startDataSource()
195 {
196  try
197  {
198  getView()->getModel()->dataStart();
199  }
200  catch(exception &e)
201  {
202  string msg = "There was an error starting the data source. \n("+string(e.what())+")";
203  WidgetUtils::AlertError("Error Starting Data Source", msg);
204  return false;
205  }
206  if(!getView()->getModel()->dataIsStarted())
207  {
208  WidgetUtils::AlertError("Error Starting Data Source", "There was an error starting the data source. Check device configuration.");
209  return false;
210  }
211  else
212  {
213  return true;
214  }
215 }
216 
218 void TabMonitor::startPlotting()
219 {
221  getView()->getModel()->dataSetStoreFlag(true);
222 
223  continue_plotting = true;
224 
225  //create the eeg plot
226  this->createPlot();
227 
228  //push status
229  if(this->collecting_data)
230  this->status_id = getView()->getStatusBar()->push("Collecting Data");
231  else
232  this->status_id = getView()->getStatusBar()->push("Plotting Data");
233 
234  //start the timeout
235  g_timeout_add(100, timedPlot, this);
236 
237  //update the widgets from model
238  updateView();
239 }
240 
241 gint TabMonitor::timedPlot(gpointer parent)
242 {
243  TabMonitor * tab = (TabMonitor*)parent;
244 
245  //if window has been reattached, end timed plot
246  if(tab->passive_plot && !tab->plot->isDetached())
247  {
248  tab->stopPlotting();
249  return false;
250  }
251  //if continue plotting has been unset, end timed plot
252  if(!tab->continuePlotting())
253  {
254  return false;
255  }
256  try
257  {
258  //read data from source. it will be put into the data buffer.
259  if(!tab->passive_plot)
260  tab->getView()->getModel()->dataReadAll();
262  int num_samples = tab->getView()->getModel()->dataGetStoreNumSamples();
263  gtk_label_set_text(GTK_LABEL(tab->label_collected_samples),
264  TextUtils::IntToString(num_samples).c_str());
265 
266  //get the data buffer to plot
267  EEGData data = tab->getView()->getModel()->dataGetStoredData();
268  if(!tab->collecting_data)
269  {
270  data = tab->getView()->getModel()->processData(data);
271  }
272  ublas::matrix<double> d = (data.getMatrix());
273 
275  if(tab->plot!=NULL)
276  {
277  tab->plot->Plot(data);
278  }
279  else
280  {
281  tab->stopPlotting();
282  }
283  if(!tab->collecting_data)
284  {
285  tab->getView()->getModel()->dataClearStoredData();
286  }
287  }
288  catch(DataExceptionUnderflow e)
289  {
290  cout << e.what() << "\n";
291  }
292  catch(DataException e)
293  {
294  cerr << e.what() << "\n";
295  tab->stopPlotting();
296  }
297  catch(PluginException e)
298  {
299  string msg = "Failed to process data. \n(" + string(e.what()) + ")";
300  WidgetUtils::AlertError("Error Processing Data",msg);
301  tab->stopPlotting();
302  }
303  catch(exception e)
304  {
305  string msg = "Failed to process data. \n(" + string(e.what()) + ")";
306  WidgetUtils::AlertError("Error Processing Data",msg);
307  tab->stopPlotting();
308  }
309  return true;
310 }
311 
313 void TabMonitor::stopPlotting()
314 {
315  if(!this->passive_plot)
316  stopDataSource();
317 
318  this->continue_plotting = false;
319  this->collecting_data = false;
320  this->passive_plot = false;
321  getView()->getModel()->dataStop();
322  getView()->getStatusBar()->remove(status_id);
323  updateView();
324 }
325 
327 void TabMonitor::stopDataSource()
328 {
329  getView()->getModel()->dataSetStoreFlag(false);
330  getView()->getModel()->dataStop();
331 }
332 
333 
334 //----------------------------------------------------------------------
335 // CALLBACKS
336 
337 
338 void TabMonitor::CB_StartMonitor(GtkWidget *w, gpointer data)
339 {
340  TabMonitor * tab = (TabMonitor*)data;
341  if(!tab->passive_plot)
342  {
343  if(tab->startDataSource())
344  tab->startPlotting();
345  }
346  else
347  {
348  tab->startPlotting();
349  }
350 }
351 void TabMonitor::CB_StopMonitor(GtkWidget *w, gpointer data)
352 {
353  TabMonitor * tab = (TabMonitor*)data;
354  if(!tab->passive_plot)
355  tab->stopDataSource();
356  tab->stopPlotting();
357 }
358 void TabMonitor::CB_StartCollect(GtkWidget *w, gpointer data)
359 {
360  TabMonitor * tab = (TabMonitor*)data;
361  tab->collecting_data = true;
362  tab->CB_StartMonitor(w,data);
363 }
364 
365 
366 void TabMonitor::CB_toggleFilter(GtkWidget *w, gpointer data)
367 {
368  TabMonitor *tab = (TabMonitor*)(data);
369  //return if callback is suppressed
370  if(!tab->updating_view)
371  {
372  bool checked =
373  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tab->check_filter));
374  tab->getView()->getModel()->processSetFilterEnabled(checked);
375  }
376 }