CEBL  2.1
EEGMonitor.cpp
Go to the documentation of this file.
1 #include "EEGMonitor.hpp"
2 #include "TextUtils.hpp"
3 #include "cppR/cppR.hpp"
4 #include "Tab.hpp"
5 #include <values.h>
6 #include <iostream>
7 
8 //constructor create widgets and initializes member variables
9 EEGMonitor::EEGMonitor(Tab *parent, int nchannels)
10 {
11  //save a pointer to the parent tab
12  this->parent_tab = parent;
13  //initialize plot
14  plot = NULL;
15  if(nchannels < 0)
16  this->num_channels = parent_tab->getView()->getModel()->channelsGetNumEnabledChannels();
17  else
18  this->num_channels = nchannels;
19  //DEFAULTS
20  num_display_samples = 0;
21  zoom = 1.0;
22  initialized = false;
23  plot_wait = false;
24 
25  //create widgets
26  GtkWidget *container = gtk_vbox_new(false, 0);
27  plot_box = gtk_vbox_new(false, 0);
28  scroll_window = gtk_scrolled_window_new(NULL,NULL);
29  gtk_container_border_width(GTK_CONTAINER(scroll_window),0);
30  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window),
31  GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
32  gtk_box_pack_start(GTK_BOX(container),scroll_window, true, true, 0);
33 
34 
35  //create controls
36  box_controls = gtk_hbox_new(false, 0);
37 
38  //num samples spin button
39  spin_samples = gtk_spin_button_new_with_range(1, MAXINT, 1);
40  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_samples),1);
41  gtk_widget_set_size_request(spin_samples, 80, 25);
42  g_signal_connect(G_OBJECT(spin_samples),
43  "value-changed",
44  G_CALLBACK(CB_ChangeNumSamples),
45  (gpointer) this);
46  //zoom spin button
47  spin_zoom = gtk_spin_button_new_with_range(.01, 500, .01);
48  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_zoom),zoom);
49  gtk_widget_set_size_request(spin_zoom, 80, 25);
50  g_signal_connect(G_OBJECT(spin_zoom),
51  "value-changed",
52  G_CALLBACK(CB_ChangeZoom),
53  (gpointer) this);
54 
55  //Place widgets
56  gtk_box_pack_start(GTK_BOX(box_controls),gtk_label_new("Currently displaying "),false,false,2);
57  gtk_box_pack_start(GTK_BOX(box_controls),spin_samples,false,false,2);
58  gtk_box_pack_start(GTK_BOX(box_controls),gtk_label_new(" samples at a time."),false,false,2);
59 
60  gtk_box_pack_end(GTK_BOX(box_controls),spin_zoom,false,false,2);
61  gtk_box_pack_end(GTK_BOX(box_controls),gtk_label_new("Zoom: "),false,false,2);
62 
63  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll_window),plot_box);
64  gtk_box_pack_start(GTK_BOX(container),box_controls,false,false,5);
65 
66  //set outer container as parent class' container
67  this->setWidgetContainer(container);
68 
69  //create plot
70  this->initPlot();
71 }
72 
73 
74 
75 //create and initialize the plot
77 {
78  this->num_channels = min(this->num_channels,72);
79  plot = new EEGPlot(this->num_channels);
80 
81  //create default labels if labels are empty, or labels defaults
82  if(labels.size() == 0 || labels[0] == "1")
83  {
84  labels.resize(0);
85  for(int i=0; i<num_channels; i++)
86  {
87  labels.push_back(TextUtils::IntToString(i+1));
88  }
89  }
90 
91 
92  //first decide on plot window sizes
93  int window_width = 0;
94  int window_height = 0;
95  if(!this->is_detached)
96  {
97  gtk_window_get_size(GTK_WINDOW(parent_tab->getView()->getMainWindow()),&window_width,&window_height);
98  window_width -= 100;
99  window_height -= 200;
100  }
101  else
102  {
103  gtk_window_get_size(GTK_WINDOW(this->detached_window),&window_width,&window_height);
104  }
105  if(num_display_samples==0)
106  num_display_samples = window_width;
107 
108  //create Plot
109  plot->setLabels(this->labels);
110  plot->setWindowWidth(window_width);
111  plot->setWindowHeight(window_height);
112  plot->setNumDisplaySamples(num_display_samples);
113  plot->setBGColor(parent_tab->getView()->getBGRED(),
114  parent_tab->getView()->getBGGREEN(),
115  parent_tab->getView()->getBGBLUE());
116 
117  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_samples),num_display_samples);
118 
119  //init plot and pack it into the window
120  plot->init();
121  gtk_box_pack_start(GTK_BOX(plot_box), (*plot), true, true, 0);
122 
123  //notify class that all plot initialization is complete at least once
124  initialized = true;
125 }
126 
127 //remove and recreate plot
128 void EEGMonitor::reInitPlot(int nchannels)
129 {
130  if(nchannels >= 0)
131  {
132  this->num_channels = nchannels;
133  this->num_channels = min(nchannels,72);
134  }
135  //set a timeout so as not to try plotting while plot doesn't exist
136  plot_wait = true;
137 
138  // if we haven't even initialized once yet, skip this
139  // otherwise remove and delete plot to prepare for a new one
140  if(initialized)
141  {
142  if(plot!=NULL)
143  {
144  gtk_container_remove(GTK_CONTAINER(plot_box),(*plot));
145  delete plot;
146  plot = NULL;
147  }
148  }
149 
150  // create the plot
151  initPlot();
152 
153  // turn off plot wait so plotting can continue
154  plot_wait = false;
155 }
156 
157 //delete plot and other allocated variables
159 {
160  if(plot!=NULL)
161  delete plot;
162 }
163 
164 /**************************************************
165  SETTERS
166 */
167 
168 /*
169  * Change visibility of controls
170  * Hides if visible = false
171  * Shows if visible = true
172  */
174 {
175  if(!visible)
176  {
177  gtk_widget_hide(box_controls);
178  gtk_widget_hide(box_controls2);
179  }
180  else
181  {
182  gtk_widget_show(box_controls);
183  gtk_widget_show(box_controls2);
184  }
185 }
186 
187 /* Set labels for the plot
188  */
189 void EEGMonitor::setLabels(std::vector<std::string> labels)
190 {
191  this->labels = labels;
192 }
193 
194 /* Set zoom for the plot
195  */
196 void EEGMonitor::setZoom(double zoom)
197 {
198  this->zoom = zoom;
199  if(plot!=NULL)
200  {
201  plot->setZoom(zoom);
202  }
203  gtk_spin_button_set_value(GTK_SPIN_BUTTON(this->spin_zoom),zoom);
204 }
205 
206 /* Set number of samples to display on the plot
207  */
209 {
210  this->num_display_samples = n;
211  if(plot!=NULL)
212  {
213  plot->setNumDisplaySamples(n);
214  }
215  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_samples),n);
216 }
217 
218 /**************************************************
219  PLOTTING
220 */
221 void EEGMonitor::Plot(ublas::matrix<double> data)
222 {
223  if(data.size2() < 1 || plot == NULL)
224  {
225  return;
226  }
227 
228  //plot wait means we are waiting for plot to be re-created
229  if(plot_wait)
230  return;
231 
232  //plot the data
233  plot->plot(data);
234 }
235 
236 
237 /**************************************************
238  CALLBACKS
239 */
240 
241 void EEGMonitor::CB_ChangeNumSamples(GtkWidget *spin, gpointer data)
242 {
243  EEGMonitor * monitor = ((EEGMonitor*)data);
244  //int old_samples = monitor->num_display_samples;
245  monitor->num_display_samples = int(gtk_spin_button_get_value(GTK_SPIN_BUTTON(monitor->spin_samples)));
246  if(monitor->plot != NULL)
247  monitor->plot->setNumDisplaySamples(monitor->num_display_samples);
248 }
249 
250 
251 void EEGMonitor::CB_ChangeZoom(GtkWidget *spin, gpointer data)
252 {
253  EEGMonitor * monitor = ((EEGMonitor*)data);
254  monitor->zoom = double(gtk_spin_button_get_value(GTK_SPIN_BUTTON(monitor->spin_zoom)));
255  if(monitor->plot != NULL)
256  monitor->plot->setZoom(monitor->zoom);
257 }
258