1 /* OpenSceneGraph example, osgkeyboard.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16 * THE SOFTWARE.
17 */
18
19 #include <osgViewer/Viewer>
20 #include <osgViewer/ViewerEventHandlers>
21 #include <osg/io_utils>
22
23 #include <osg/MatrixTransform>
24 #include <osg/Geode>
25 #include <osg/Group>
26 #include <osg/Switch>
27 #include <osg/Notify>
28 #include <osg/Geometry>
29
30 #include <osgText/Text>
31
32 #include <osgDB/Registry>
33 #include <osgDB/ReadFile>
34 #include <osgDB/WriteFile>
35
36
37 class KeyboardModel : public osg::Referenced
38 {
39 public:
40
KeyboardModel()41 KeyboardModel() { createKeyboard(); }
42
getScene()43 osg::Group* getScene() { return _scene.get(); }
44
45 void keyChange(int key, int virtualKey, int value);
46
47 protected:
48
~KeyboardModel()49 ~KeyboardModel() {}
50
51 osg::Switch* addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height);
52
53 void createKeyboard();
54
55 typedef std::map<int, osg::ref_ptr<osg::Switch> > KeyModelMap;
56
57 osg::ref_ptr<osg::Group> _scene;
58 KeyModelMap _keyModelMap;
59 osg::ref_ptr<osgText::Text> _inputText;
60
61 };
62
keyChange(int key,int virtualKey,int value)63 void KeyboardModel::keyChange(int key, int virtualKey, int value)
64 {
65 osg::notify(osg::INFO) << "key value change, code="<<std::hex << key << "\t value="<< value << std::dec << std::endl;
66
67 // toggle the keys graphical representation on or off via osg::Swithc
68 KeyModelMap::iterator itr = _keyModelMap.find(virtualKey);
69 if (itr!=_keyModelMap.end())
70 {
71 itr->second->setSingleChildOn(value);
72 }
73
74 if (value)
75 {
76 // when a key is pressed add the new data to the text field
77
78 if (key>0 && key<256)
79 {
80 // just add ascii characters right now...
81 _inputText->getText().push_back(key);
82 _inputText->update();
83 }
84 else if (key==osgGA::GUIEventAdapter::KEY_Return)
85 {
86 _inputText->getText().push_back('\n');
87 _inputText->update();
88 }
89 else if (key==osgGA::GUIEventAdapter::KEY_BackSpace || key==osgGA::GUIEventAdapter::KEY_Delete)
90 {
91 if (!_inputText->getText().empty())
92 {
93 _inputText->getText().pop_back();
94 _inputText->update();
95 }
96 }
97
98 }
99
100 }
101
addKey(osg::Vec3 & pos,int key,const std::string & text,float width,float height)102 osg::Switch* KeyboardModel::addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height)
103 {
104
105 osg::Geode* geodeUp = new osg::Geode;
106 {
107 osgText::Text* textUp = new osgText::Text;
108 textUp->setFont("fonts/arial.ttf");
109 textUp->setColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
110 textUp->setCharacterSize(height);
111 textUp->setPosition(pos);
112 textUp->setDrawMode(osgText::Text::TEXT/*|osgText::Text::BOUNDINGBOX*/);
113 textUp->setAlignment(osgText::Text::LEFT_CENTER);
114 textUp->setAxisAlignment(osgText::Text::XZ_PLANE);
115 textUp->setText(text);
116
117 geodeUp->addDrawable(textUp);
118 }
119
120 osg::Geode* geodeDown = new osg::Geode;
121 {
122 osgText::Text* textDown = new osgText::Text;
123 textDown->setFont("fonts/arial.ttf");
124 textDown->setColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));
125 textDown->setCharacterSize(height);
126 textDown->setPosition(pos);
127 textDown->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
128 textDown->setAlignment(osgText::Text::LEFT_CENTER);
129 textDown->setAxisAlignment(osgText::Text::XZ_PLANE);
130 textDown->setText(text);
131
132 geodeDown->addDrawable(textDown);
133 }
134
135 osg::Switch* model = new osg::Switch;
136 model->addChild(geodeUp,true);
137 model->addChild(geodeDown,false);
138
139 _scene->addChild(model);
140
141 _keyModelMap[key] = model;
142
143 pos.x() += width;
144
145 return model;
146
147 }
148
createKeyboard()149 void KeyboardModel::createKeyboard()
150 {
151 _scene = new osg::Group;
152
153 osg::Vec3 origin(0.0f,0.0f,0.0f);
154 osg::Vec3 pos=origin;
155
156 addKey(pos,osgGA::GUIEventAdapter::KEY_Control_L,"Ctrl",2.0f,0.5f);
157 addKey(pos,osgGA::GUIEventAdapter::KEY_Super_L,"Super",2.0f,0.5f);
158 addKey(pos,osgGA::GUIEventAdapter::KEY_Alt_L,"Alt",2.0f,0.5f);
159 addKey(pos,osgGA::GUIEventAdapter::KEY_Space,"Space",3.0f,1.0f);
160 addKey(pos,osgGA::GUIEventAdapter::KEY_Mode_switch,"Switch",2.0f,0.5f);
161 addKey(pos,osgGA::GUIEventAdapter::KEY_Super_R,"Super",2.0f,0.5f);
162 addKey(pos,osgGA::GUIEventAdapter::KEY_Menu,"Menu",2.0f,0.5f);
163 addKey(pos,osgGA::GUIEventAdapter::KEY_Control_R,"Ctrl",2.0f,0.5f);
164
165 osg::Vec3 middle(pos.x()+1.0f,0.0f,0.0f);
166
167 pos.x() = 0.0f;
168 pos.z() += 1.0f;
169
170 addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_L,"Shift",2.0f,0.5f);
171 addKey(pos,osgGA::GUIEventAdapter::KEY_Backslash,"\\",1.0f,1.0f);
172 addKey(pos,osgGA::GUIEventAdapter::KEY_Z,"Z",1.0f,1.0f);
173 addKey(pos,osgGA::GUIEventAdapter::KEY_X,"X",1.0f,1.0f);
174 addKey(pos,osgGA::GUIEventAdapter::KEY_C,"C",1.0f,1.0f);
175 addKey(pos,osgGA::GUIEventAdapter::KEY_V,"V",1.0f,1.0f);
176 addKey(pos,osgGA::GUIEventAdapter::KEY_B,"B",1.0f,1.0f);
177 addKey(pos,osgGA::GUIEventAdapter::KEY_N,"N",1.0f,1.0f);
178 addKey(pos,osgGA::GUIEventAdapter::KEY_M,"M",1.0f,1.0f);
179 addKey(pos,osgGA::GUIEventAdapter::KEY_Comma,",",1.0f,1.0f);
180 addKey(pos,osgGA::GUIEventAdapter::KEY_Period,".",1.0f,1.0f);
181 addKey(pos,osgGA::GUIEventAdapter::KEY_Slash,"/",1.0f,1.0f);
182 addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_R,"Shift",2.0f,0.5f);
183
184 pos.x() = 0.0f;
185 pos.z() += 1.0f;
186
187 addKey(pos,osgGA::GUIEventAdapter::KEY_Caps_Lock,"Caps",2.0f,0.5f);
188 addKey(pos,osgGA::GUIEventAdapter::KEY_A,"A",1.0f,1.0f);
189 addKey(pos,osgGA::GUIEventAdapter::KEY_S,"S",1.0f,1.0f);
190 addKey(pos,osgGA::GUIEventAdapter::KEY_D,"D",1.0f,1.0f);
191 addKey(pos,osgGA::GUIEventAdapter::KEY_F,"F",1.0f,1.0f);
192 addKey(pos,osgGA::GUIEventAdapter::KEY_G,"G",1.0f,1.0f);
193 addKey(pos,osgGA::GUIEventAdapter::KEY_H,"H",1.0f,1.0f);
194 addKey(pos,osgGA::GUIEventAdapter::KEY_J,"J",1.0f,1.0f);
195 addKey(pos,osgGA::GUIEventAdapter::KEY_K,"K",1.0f,1.0f);
196 addKey(pos,osgGA::GUIEventAdapter::KEY_L,"L",1.0f,1.0f);
197 addKey(pos,osgGA::GUIEventAdapter::KEY_Semicolon,";",1.0f,1.0f);
198 addKey(pos,osgGA::GUIEventAdapter::KEY_Quote,"'",1.0f,1.0f);
199 addKey(pos,osgGA::GUIEventAdapter::KEY_Hash,"#",1.0f,1.0f);
200 addKey(pos,osgGA::GUIEventAdapter::KEY_Return,"Return",4.0f,0.5f);
201
202 pos.x() = 0.0f;
203 pos.z() += 1.0f;
204
205 addKey(pos,osgGA::GUIEventAdapter::KEY_Tab,"Tab",2.0f,0.5f);
206 addKey(pos,osgGA::GUIEventAdapter::KEY_Q,"Q",1.0f,1.0f);
207 addKey(pos,osgGA::GUIEventAdapter::KEY_W,"W",1.0f,1.0f);
208 addKey(pos,osgGA::GUIEventAdapter::KEY_E,"E",1.0f,1.0f);
209 addKey(pos,osgGA::GUIEventAdapter::KEY_R,"R",1.0f,1.0f);
210 addKey(pos,osgGA::GUIEventAdapter::KEY_T,"T",1.0f,1.0f);
211 addKey(pos,osgGA::GUIEventAdapter::KEY_Y,"Y",1.0f,1.0f);
212 addKey(pos,osgGA::GUIEventAdapter::KEY_U,"U",1.0f,1.0f);
213 addKey(pos,osgGA::GUIEventAdapter::KEY_I,"I",1.0f,1.0f);
214 addKey(pos,osgGA::GUIEventAdapter::KEY_O,"O",1.0f,1.0f);
215 addKey(pos,osgGA::GUIEventAdapter::KEY_P,"P",1.0f,1.0f);
216 addKey(pos,osgGA::GUIEventAdapter::KEY_Leftbracket,"[",1.0f,1.0f);
217 addKey(pos,osgGA::GUIEventAdapter::KEY_Rightbracket,"]",1.0f,1.0f);
218
219 pos.x() = 0.0f;
220 pos.z() += 1.0f;
221
222 addKey(pos,osgGA::GUIEventAdapter::KEY_Backquote,"`",1.0f,1.0f);
223 addKey(pos,osgGA::GUIEventAdapter::KEY_1,"1",1.0f,1.0f);
224 addKey(pos,osgGA::GUIEventAdapter::KEY_2,"2",1.0f,1.0f);
225 addKey(pos,osgGA::GUIEventAdapter::KEY_3,"3",1.0f,1.0f);
226 addKey(pos,osgGA::GUIEventAdapter::KEY_4,"4",1.0f,1.0f);
227 addKey(pos,osgGA::GUIEventAdapter::KEY_5,"5",1.0f,1.0f);
228 addKey(pos,osgGA::GUIEventAdapter::KEY_6,"6",1.0f,1.0f);
229 addKey(pos,osgGA::GUIEventAdapter::KEY_7,"7",1.0f,1.0f);
230 addKey(pos,osgGA::GUIEventAdapter::KEY_8,"8",1.0f,1.0f);
231 addKey(pos,osgGA::GUIEventAdapter::KEY_9,"9",1.0f,1.0f);
232 addKey(pos,osgGA::GUIEventAdapter::KEY_0,"0",1.0f,1.0f);
233 addKey(pos,osgGA::GUIEventAdapter::KEY_Minus,"-",1.0f,1.0f);
234 addKey(pos,osgGA::GUIEventAdapter::KEY_Equals,"=",1.0f,1.0f);
235 addKey(pos,osgGA::GUIEventAdapter::KEY_BackSpace,"Backspace",3.0f,0.5f);
236
237 pos.x() = 0.0f;
238 pos.z() += 1.5f;
239
240 float F_height = 0.5f;
241 addKey(pos,osgGA::GUIEventAdapter::KEY_Escape,"Esc",2.0f,F_height);
242 addKey(pos,osgGA::GUIEventAdapter::KEY_F1,"F1",1.0f,F_height);
243 addKey(pos,osgGA::GUIEventAdapter::KEY_F2,"F2",1.0f,F_height);
244 addKey(pos,osgGA::GUIEventAdapter::KEY_F3,"F3",1.0f,F_height);
245 addKey(pos,osgGA::GUIEventAdapter::KEY_F4,"F4",1.0f,F_height);
246 addKey(pos,osgGA::GUIEventAdapter::KEY_F5,"F5",1.0f,F_height);
247 addKey(pos,osgGA::GUIEventAdapter::KEY_F6,"F6",1.0f,F_height);
248 addKey(pos,osgGA::GUIEventAdapter::KEY_F7,"F7",1.0f,F_height);
249 addKey(pos,osgGA::GUIEventAdapter::KEY_F8,"F8",1.0f,F_height);
250 addKey(pos,osgGA::GUIEventAdapter::KEY_F9,"F9",1.0f,F_height);
251 addKey(pos,osgGA::GUIEventAdapter::KEY_F10,"F10",1.0f,F_height);
252 addKey(pos,osgGA::GUIEventAdapter::KEY_F11,"F11",1.0f,F_height);
253 addKey(pos,osgGA::GUIEventAdapter::KEY_F12,"F12",1.0f,F_height);
254
255
256
257 float cursorMoveHeight=0.35f;
258
259 pos = middle;
260 addKey(pos,osgGA::GUIEventAdapter::KEY_Left,"Left",1.0f,cursorMoveHeight);
261 osg::Vec3 down = pos;
262 addKey(pos,osgGA::GUIEventAdapter::KEY_Down,"Down",1.0f,cursorMoveHeight);
263 addKey(pos,osgGA::GUIEventAdapter::KEY_Right,"Right",1.0f,cursorMoveHeight);
264
265 osg::Vec3 keypad = pos;
266 keypad.x()+=1.0f;
267
268 pos = down;
269 pos.z() += 1.0f;
270
271 addKey(pos,osgGA::GUIEventAdapter::KEY_Up,"Up",1.0f,cursorMoveHeight);
272
273
274 float homeHeight = 0.35f;
275 pos = middle;
276 pos.z() += 3.0;
277 addKey(pos,osgGA::GUIEventAdapter::KEY_Delete,"Delete",1.0f,homeHeight);
278 addKey(pos,osgGA::GUIEventAdapter::KEY_End,"End",1.0f,homeHeight);
279 addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Down,"Page\nDown",1.0f,homeHeight);
280
281 pos = middle;
282 pos.z() += 4.0;
283 addKey(pos,osgGA::GUIEventAdapter::KEY_Insert,"Insert",1.0f,homeHeight);
284 addKey(pos,osgGA::GUIEventAdapter::KEY_Home,"Home",1.0f,homeHeight);
285 addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Up,"Page\nUp",1.0f,homeHeight);
286
287 pos = middle;
288 pos.z() += 5.5;
289 addKey(pos,osgGA::GUIEventAdapter::KEY_Print,"PrtScrn\nSysRq",1.0f,homeHeight);
290 addKey(pos,osgGA::GUIEventAdapter::KEY_Scroll_Lock,"ScrLk",1.0f,homeHeight);
291 addKey(pos,osgGA::GUIEventAdapter::KEY_Pause,"Pause\nBreak",1.0f,homeHeight);
292
293
294
295 pos = keypad;
296 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Insert,"0",2.0f,1.0f);
297 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Delete,".",1.0f,1.0f);
298 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Enter,"Enter",1.0f,homeHeight);
299
300 pos = keypad;
301 pos.z() += 1.0f;
302 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_End,"1",1.0f,1.0f);
303 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Down,"2",1.0f,1.0f);
304 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Down,"3",1.0f,1.0f);
305
306 pos = keypad;
307 pos.z() += 2.0f;
308 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Left,"4",1.0f,1.0f);
309 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Begin,"5",1.0f,1.0f);
310 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Right,"6",1.0f,1.0f);
311 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Add,"+",1.0f,1.0f);
312
313 pos = keypad;
314 pos.z() += 3.0f;
315 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Home,"7",1.0f,1.0f);
316 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Up,"8",1.0f,1.0f);
317 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Up,"9",1.0f,1.0f);
318
319 pos = keypad;
320 pos.z() += 4.0f;
321 addKey(pos,osgGA::GUIEventAdapter::KEY_Num_Lock,"Num\nLock",1.0f,0.3f);
322 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Divide,"/",1.0f,1.0f);
323 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Multiply,"*",1.0f,1.0f);
324 addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Subtract,"-",1.0f,1.0f);
325
326 float totalWidth = pos.x()-origin.x();
327 pos = origin;
328 pos.z() += -1.5f;
329
330 osg::Geode* geodeInput = new osg::Geode;
331 {
332 _inputText = new osgText::Text;
333 _inputText->setFont("fonts/arial.ttf");
334 _inputText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
335 _inputText->setCharacterSize(1.0f);
336 _inputText->setMaximumWidth(totalWidth);
337 _inputText->setPosition(pos);
338 _inputText->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
339 _inputText->setAlignment(osgText::Text::BASE_LINE);
340 _inputText->setAxisAlignment(osgText::Text::XZ_PLANE);
341 _inputText->setDataVariance(osg::Object::DYNAMIC);
342 _inputText->setText("Press some keys...");
343
344 geodeInput->addDrawable(_inputText.get());
345
346 _scene->addChild(geodeInput);
347 }
348
349 }
350
351
352
353
354
355
356 class KeyboardEventHandler : public osgGA::GUIEventHandler
357 {
358 public:
359
KeyboardEventHandler(KeyboardModel * keyboardModel)360 KeyboardEventHandler(KeyboardModel* keyboardModel):
361 _keyboardModel(keyboardModel) {}
362
handle(const osgGA::GUIEventAdapter & ea,osgGA::GUIActionAdapter &)363 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
364 {
365
366 #if 1
367
368 // osg::notify(osg::NOTICE)<<"Mouse "<<ea.getButtonMask()<<std::endl;
369
370 #define PRINT(mask) osg::notify(osg::NOTICE)<<#mask<<" ="<<(ea.getModKeyMask() & mask)<<std::endl;
371 switch(ea.getEventType())
372 {
373 case(osgGA::GUIEventAdapter::KEYDOWN):
374 case(osgGA::GUIEventAdapter::KEYUP):
375 {
376 osg::notify(osg::NOTICE)<<std::endl;
377 PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT);
378 PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT);
379 PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_ALT);
380 PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT);
381 PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL);
382 PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL);
383 PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_META);
384 PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_META);
385 PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_SUPER);
386 PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_SUPER);
387 PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_HYPER);
388 PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_HYPER);
389 PRINT(osgGA::GUIEventAdapter::MODKEY_NUM_LOCK);
390 PRINT(osgGA::GUIEventAdapter::MODKEY_CAPS_LOCK);
391 break;
392 }
393 default:
394 break;
395 }
396 #endif
397 switch(ea.getEventType())
398 {
399 case(osgGA::GUIEventAdapter::KEYDOWN):
400 {
401 _keyboardModel->keyChange(ea.getKey(), ea.getUnmodifiedKey(),1);
402 return true;
403 }
404 case(osgGA::GUIEventAdapter::KEYUP):
405 {
406 _keyboardModel->keyChange(ea.getKey(), ea.getUnmodifiedKey(),0);
407 return true;
408 }
409
410 default:
411 return false;
412 }
413 }
414
415 osg::ref_ptr<KeyboardModel> _keyboardModel;
416
417 };
418
main(int,char **)419 int main(int , char **)
420 {
421 osgViewer::Viewer viewer;
422
423 osg::ref_ptr<KeyboardModel> keyboardModel = new KeyboardModel;
424
425 viewer.addEventHandler(new osgViewer::StatsHandler);
426 viewer.addEventHandler(new osgViewer::WindowSizeHandler());
427 viewer.addEventHandler(new KeyboardEventHandler(keyboardModel.get()));
428 viewer.setSceneData( keyboardModel->getScene() );
429
430 return viewer.run();
431 }
432