root/OpenSceneGraph/trunk/examples/osgkeyboard/osgkeyboard.cpp @ 13375

Revision 12125, 16.1 kB (checked in by robert, 4 years ago)

From Alexander Sinditskiy, "reason of this changes described in http://forum.openscenegraph.org/viewtopic.php?t=7596

and another problem is:
example osgkeyboard is not work (keys not highlight) if user have 2 keyboard layout native and english and current user layout is native

I try to explain my changes

we need something that is identify key without modifier keys and layout -> this is UnmodifedKey?

I think osg must have its own UnmodifiedKeys? table. Code must be run same on different platforms. This can de guaranteed by UnmodifiedKeys? table.

Mikhail Izmestev helped me. He implemented VirtualKey? changes in GraphicsWindowX11"

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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
37class KeyboardModel : public osg::Referenced
38{
39public:
40
41        KeyboardModel() { createKeyboard(); }
42       
43        osg::Group* getScene() { return _scene.get(); }
44       
45        void keyChange(int key, int virtualKey, int value);
46       
47protected:
48       
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
63void 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
102osg::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
149void 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
356class KeyboardEventHandler : public osgGA::GUIEventHandler
357{
358public:
359   
360        KeyboardEventHandler(KeyboardModel* keyboardModel):
361            _keyboardModel(keyboardModel) {}
362   
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
419int 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}
Note: See TracBrowser for help on using the browser.