CEBL  2.1
KeyboardPie.cpp
Go to the documentation of this file.
1 /* KeyboardPie.cpp
2  * \author Jeshua Bratman
3  *
4  * Keyboard interface for CEBL
5  */
6 
7 
8 #include "KeyboardPie.hpp"
9 #include "../X11Controller.hpp"
10 #include <iostream>
11 
13 {
14  //init everything
15  init();
16 
17  //create vectors
18  alphabet.resize(26);
19  for(unsigned int i=0; i<alphabet.size();i++)
20  {
21  char letter = char(i+0x41);
22  alphabet[i] = letter;
23  }
24  punctuation.resize(5);
25  punctuation[0] = ".";
26  punctuation[1] = ",";
27  punctuation[2] = "?";
28  punctuation[3] = "!";
29  punctuation[4] = "\"";
30 
31  special.resize(3);
32  special[0] = "[BACKSPACE]";
33  special_keys[special[0]] = "BackSpace";
34  special[1] = "[ENTER]";
35  special_keys[special[1]] = "Return";
36  special[2] = "[SPACE]";
37  special_keys[special[2]] = "space";
38 
39  back_level.resize(1);
40  back_level[0] = "BACK";
41 
42  //testing
43  classes.push_back(0);
44  classes.push_back(1);
45  classes.push_back(0);
46  classes.push_back(2);
47  classes.push_back(2);
48  classes.push_back(2);
49  index = 0;
50 
51  GtkWidget *hbox_type = gtk_hbox_new(false,0);
52  typing_box = gtk_entry_new();
53  check_send_keys = gtk_check_button_new_with_label("Send Keyboard Events?");
54  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_send_keys),true);
55  send_keys = true;
56 
57  gtk_widget_set_size_request(typing_box,300,20);
58  gtk_box_pack_start(GTK_BOX(hbox_type),gtk_label_new("Typed Characters: "),false, false, 0);
59  gtk_box_pack_start(GTK_BOX(hbox_type),typing_box,false, false, 0);
60  gtk_box_pack_end(GTK_BOX(hbox_type),check_send_keys,false, false, 0);
61  packStart(hbox_type);
62 }
63 
64 void KeyboardPie::init()
65 {
66  use_special = false;
67 
68  //initial mode
69  mode = SELECT_MODE;
70 }
71 
73 {
74  num_classes = n;
76  updateNames();
77 }
78 
79 void KeyboardPie::updateNames()
80 {
81  if(num_classes > 2)
82  use_special = true;
83  else
84  use_special = false;
85 
86 
87  //select mode shows all sets of keys
88  if(mode==SELECT_MODE)
89  {
90 
91  if(use_special)
92  {
93  //set first class to special functions
94  current_labels[0] = special;
95  split(alphabet,1,num_classes);
96  }
97  else
98  {
99  split(alphabet,0,num_classes);
100  }
101  }
102  else
103  {
104  if(use_special)
105  {
106  current_labels[0] = back_level;
107  split(key_pool,1,num_classes);
108  }
109  else
110  {
111  split(key_pool,0,num_classes);
112  }
113  }
114  //create labels vector
115  vector<string> labels;
116  labels.resize(num_classes);
117  for(unsigned int i=0; i<unsigned(num_classes); i++)
118  {
119  labels[i] = "";
120  if(current_labels[i].size() > 8)
121  {
122  labels[i] = current_labels[i][0] + " - "
123  +current_labels[i][current_labels[i].size()-1];
124  }
125  else
126  {
127  for(unsigned int j=0; j<current_labels[i].size(); j++)
128  {
129  if(i != 1
130  && mode!=PUNCTUATION_MODE
131  && !(i==0 && mode!=SELECT_MODE && use_special==false)
132  && (j+1) != current_labels[i].size())
133  labels[i] += current_labels[i][j] + ", ";
134  else
135  labels[i] += current_labels[i][j] + " ";
136  }
137  }
138  }
140 }
141 
142 void KeyboardPie::split(vector<string> keys, int start, int end)
143 {
144  int num = end-start;
145  if(num < 1)
146  return;
147 
148  int count = 0;
149  int i = 0;
150  for(int cls=start; cls < end; cls++)
151  {
152  current_labels[cls].clear();
153  current_labels[cls].resize(0);
154  i++;
155  for(unsigned int key=count; key<keys.size(); key++)
156  {
157  if(count >= int(i * keys.size()/num))
158  break;
159  current_labels[cls].push_back(keys[key]);
160  count++;
161  }
162  }
163 }
164 
166 {
167 
168  if(c == -1)
169  {
171  init();
172  updateNames();
173  }
174  else
175  {
176  //for testing purposes
177  //c = classes[index];;
178  //c = rand() % num_classes;
179  if(mode!=SELECT_MODE && current_labels[c].size() < 1)
180  return;
181 
184  selectPie(c);
185  }
186 }
187 
188 
189 void KeyboardPie::selectPie(int c)
190 {
191  index++;
192  if(unsigned(index) >= classes.size())
193  index = 0;
194  if(mode == SELECT_MODE)
195  {
196  if(use_special)
197  {
198  if(c==0)
199  {
200  mode = SPECIAL_MODE;
201  key_pool = special;
202  }
203  /*else if(c==1)
204  {
205  mode = PUNCTUATION_MODE;
206  key_pool = punctuation;
207  }*/
208  else
209  {
210  mode = ALPHABET_MODE;
211  key_pool = current_labels[c];
212  }
213 
214  }
215  else
216  {
217  /*if(c==1)
218  {
219  mode = PUNCTUATION_MODE;
220  key_pool = punctuation;
221  }
222  else*/
223  {
224  mode = ALPHABET_MODE;
225  key_pool = current_labels[c];
226  }
227  }
228  }
229  else
230  {
231  if(c!=0 && current_labels[c].size() == 1)
232  {
233  send_keys = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_send_keys));
234  string key = current_labels[c][0];
235  if(mode == SPECIAL_MODE)
236  {
237  key = special_keys[current_labels[c][0]];
238  }
239  if(send_keys)
240  {
241  cout << "sending " << key << "\n";
242  //send the key to the display
243  X11Controller x;
244  if(x.displayIsOpen())
245  {
246  x.keySend(key.c_str());
247  }
248  }
249  while(!key_pool_stack.empty())
250  key_pool_stack.pop();
251  mode = SELECT_MODE;
252  }
253  else
254  {
255  //if number of classes > 2, c=0 is the back button
256  //go back
257  if(c == 0 && num_classes > 2)
258  {
259  if(key_pool_stack.empty())
260  {
261  mode = SELECT_MODE;
262  }
263  else
264  {
265  key_pool = key_pool_stack.top();
266  key_pool_stack.pop();
267  }
268  }
269  //select characters from the character pool
270  else
271  {
272  key_pool_stack.push(key_pool);
273  key_pool = current_labels[c];
274  }
275  }
276  }
277  updateNames();
278 }
279 
280 
281 //----------------------------------------
282 //parameters
283 std::map<std::string, CEBL::Param> KeyboardPie::getParamsList()
284 {
285  std::map<std::string, CEBL::Param> params;
286  return params;
287 }
288 void KeyboardPie::setParamsList(std::map<std::string, CEBL::Param> p)
289 {
290 }