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

Revision 7112, 15.0 kB (checked in by robert, 7 years ago)

Introduced new GUIEventAdatper singleton for sharing the current state between
multiple GraphicsWindows?, this singleton is accessable via GUIEventEvent::getAccumulatedEventState().

Added use of this new singleton in GraphicsWindow?* implementations.

Added WindowSizeHandler? to osgkeyboard to help with debugging of event state
between windows.

  • 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 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        osg::Switch* addKey(int key,osg::Switch* sw);
53
54        void createKeyboard();
55
56        typedef std::map<int, osg::ref_ptr<osg::Switch> > KeyModelMap;
57       
58        osg::ref_ptr<osg::Group>    _scene;
59        KeyModelMap                 _keyModelMap;
60        osg::ref_ptr<osgText::Text> _inputText;
61
62};
63
64void KeyboardModel::keyChange(int key,int value)
65{
66    osg::notify(osg::INFO) << "key value change, code="<<std::hex << key << "\t value="<< value << std::dec  << std::endl;
67
68    // toggle the keys graphical representation on or off via osg::Swithc
69    KeyModelMap::iterator itr = _keyModelMap.find(key);
70    if (itr!=_keyModelMap.end())
71    {
72        itr->second->setSingleChildOn(value);
73    }
74   
75    if (value)
76    {
77        // when a key is pressed add the new data to the text field
78       
79        if (key>0 && key<256)
80        {
81            // just add ascii characters right now...
82            _inputText->getText().push_back(key);
83            _inputText->update();
84        }
85        else if (key==osgGA::GUIEventAdapter::KEY_Return)
86        {
87            _inputText->getText().push_back('\n');
88            _inputText->update();
89        }
90        else if (key==osgGA::GUIEventAdapter::KEY_BackSpace || key==osgGA::GUIEventAdapter::KEY_Delete)
91        {
92            if (!_inputText->getText().empty())
93            {
94                _inputText->getText().pop_back();
95                _inputText->update();
96            }
97        }
98       
99    }
100   
101}
102
103osg::Switch* KeyboardModel::addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height)
104{
105
106    osg::Geode* geodeUp = new osg::Geode;
107    {
108        osgText::Text* textUp = new osgText::Text;
109        textUp->setFont("fonts/arial.ttf");
110        textUp->setColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
111        textUp->setCharacterSize(height);
112        textUp->setPosition(pos);
113        textUp->setDrawMode(osgText::Text::TEXT/*|osgText::Text::BOUNDINGBOX*/);
114        textUp->setAlignment(osgText::Text::LEFT_CENTER);
115        textUp->setAxisAlignment(osgText::Text::XZ_PLANE);
116        textUp->setText(text);
117       
118        geodeUp->addDrawable(textUp);
119    }
120   
121    osg::Geode* geodeDown = new osg::Geode;
122    {
123        osgText::Text* textDown = new osgText::Text;
124        textDown->setFont("fonts/arial.ttf");
125        textDown->setColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));
126        textDown->setCharacterSize(height);
127        textDown->setPosition(pos);
128        textDown->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
129        textDown->setAlignment(osgText::Text::LEFT_CENTER);
130        textDown->setAxisAlignment(osgText::Text::XZ_PLANE);
131        textDown->setText(text);
132       
133        geodeDown->addDrawable(textDown);
134    }
135
136    osg::Switch* model = new osg::Switch;
137    model->addChild(geodeUp,true);
138    model->addChild(geodeDown,false);
139   
140    _scene->addChild(model);
141
142    _keyModelMap[key] = model;
143   
144    pos.x() += width;
145   
146    return model;
147   
148}
149
150osg::Switch* KeyboardModel::addKey(int key,osg::Switch* sw)
151{
152    _keyModelMap[key] = sw;
153    return sw;
154}
155
156void KeyboardModel::createKeyboard()
157{
158    _scene = new osg::Group;
159   
160    osg::Vec3 origin(0.0f,0.0f,0.0f);
161    osg::Vec3 pos=origin;
162   
163    addKey(pos,osgGA::GUIEventAdapter::KEY_Control_L,"Ctrl",2.0f,0.5f);
164    addKey(pos,osgGA::GUIEventAdapter::KEY_Super_L,"Super",2.0f,0.5f);
165    addKey(pos,osgGA::GUIEventAdapter::KEY_Alt_L,"Alt",2.0f,0.5f);
166    addKey(pos,osgGA::GUIEventAdapter::KEY_Space,"Space",3.0f,1.0f);
167    addKey(pos,osgGA::GUIEventAdapter::KEY_Mode_switch,"Switch",2.0f,0.5f);
168    addKey(pos,osgGA::GUIEventAdapter::KEY_Super_R,"Super",2.0f,0.5f);
169    addKey(pos,osgGA::GUIEventAdapter::KEY_Menu,"Menu",2.0f,0.5f);
170    addKey(pos,osgGA::GUIEventAdapter::KEY_Control_R,"Ctrl",2.0f,0.5f);
171
172    osg::Vec3 middle(pos.x()+1.0f,0.0f,0.0f);
173   
174    pos.x() = 0.0f;
175    pos.z() += 1.0f;
176
177    addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_L,"Shift",2.0f,0.5f);
178    addKey(pos,'\\',"\\",1.0f,1.0f);
179    addKey('Z',addKey(pos,'z',"Z",1.0f,1.0f));
180    addKey('X',addKey(pos,'x',"X",1.0f,1.0f));
181    addKey('C',addKey(pos,'c',"C",1.0f,1.0f));
182    addKey('V',addKey(pos,'v',"V",1.0f,1.0f));
183    addKey('B',addKey(pos,'b',"B",1.0f,1.0f));
184    addKey('N',addKey(pos,'n',"N",1.0f,1.0f));
185    addKey('M',addKey(pos,'m',"M",1.0f,1.0f));
186    addKey('<',addKey(pos,',',",",1.0f,1.0f));
187    addKey('>',addKey(pos,'.',".",1.0f,1.0f));
188    addKey('?',addKey(pos,'/',"/",1.0f,1.0f));
189    addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_R,"Shift",2.0f,0.5f);
190
191    pos.x() = 0.0f;
192    pos.z() += 1.0f;
193   
194    addKey(pos,osgGA::GUIEventAdapter::KEY_Caps_Lock,"Caps",2.0f,0.5f);
195    addKey('A',addKey(pos,'a',"A",1.0f,1.0f));
196    addKey('S',addKey(pos,'s',"S",1.0f,1.0f));
197    addKey('D',addKey(pos,'d',"D",1.0f,1.0f));
198    addKey('F',addKey(pos,'f',"F",1.0f,1.0f));
199    addKey('G',addKey(pos,'g',"G",1.0f,1.0f));
200    addKey('H',addKey(pos,'h',"H",1.0f,1.0f));
201    addKey('J',addKey(pos,'j',"J",1.0f,1.0f));
202    addKey('K',addKey(pos,'k',"K",1.0f,1.0f));
203    addKey('L',addKey(pos,'l',"L",1.0f,1.0f));
204    addKey(':',addKey(pos,';',";",1.0f,1.0f));
205    addKey('@',addKey(pos,'\'',"'",1.0f,1.0f));
206    addKey('~',addKey(pos,'#',"#",1.0f,1.0f));
207    addKey(pos,osgGA::GUIEventAdapter::KEY_Return,"Return",4.0f,0.5f);
208
209    pos.x() = 0.0f;
210    pos.z() += 1.0f;
211   
212    addKey(pos,osgGA::GUIEventAdapter::KEY_Tab,"Tab",2.0f,0.5f);
213    addKey('Q',addKey(pos,'q',"Q",1.0f,1.0f));
214    addKey('W',addKey(pos,'w',"W",1.0f,1.0f));
215    addKey('E',addKey(pos,'e',"E",1.0f,1.0f));
216    addKey('R',addKey(pos,'r',"R",1.0f,1.0f));
217    addKey('T',addKey(pos,'t',"T",1.0f,1.0f));
218    addKey('Y',addKey(pos,'y',"Y",1.0f,1.0f));
219    addKey('U',addKey(pos,'u',"U",1.0f,1.0f));
220    addKey('I',addKey(pos,'i',"I",1.0f,1.0f));
221    addKey('O',addKey(pos,'o',"O",1.0f,1.0f));
222    addKey('P',addKey(pos,'p',"P",1.0f,1.0f));
223    addKey('{',addKey(pos,'[',"[",1.0f,1.0f));
224    addKey('}',addKey(pos,']',"]",1.0f,1.0f));
225
226    pos.x() = 0.0f;
227    pos.z() += 1.0f;
228   
229    addKey(pos,'`',"`",1.0f,1.0f);
230    addKey(pos,'1',"1",1.0f,1.0f);
231    addKey(pos,'2',"2",1.0f,1.0f);
232    addKey(pos,'3',"3",1.0f,1.0f);
233    addKey(pos,'4',"4",1.0f,1.0f);
234    addKey(pos,'5',"5",1.0f,1.0f);
235    addKey(pos,'6',"6",1.0f,1.0f);
236    addKey(pos,'7',"7",1.0f,1.0f);
237    addKey(pos,'8',"8",1.0f,1.0f);
238    addKey(pos,'9',"9",1.0f,1.0f);
239    addKey(pos,'0',"0",1.0f,1.0f);
240    addKey(pos,'-',"-",1.0f,1.0f);
241    addKey(pos,'=',"=",1.0f,1.0f);
242    addKey(pos,osgGA::GUIEventAdapter::KEY_BackSpace,"Backspace",3.0f,0.5f);
243
244    pos.x() = 0.0f;
245    pos.z() += 1.5f;
246   
247    float F_height = 0.5f;
248    addKey(pos,osgGA::GUIEventAdapter::KEY_Escape,"Esc",2.0f,F_height);
249    addKey(pos,osgGA::GUIEventAdapter::KEY_F1,"F1",1.0f,F_height);
250    addKey(pos,osgGA::GUIEventAdapter::KEY_F2,"F2",1.0f,F_height);
251    addKey(pos,osgGA::GUIEventAdapter::KEY_F3,"F3",1.0f,F_height);
252    addKey(pos,osgGA::GUIEventAdapter::KEY_F4,"F4",1.0f,F_height);
253    addKey(pos,osgGA::GUIEventAdapter::KEY_F5,"F5",1.0f,F_height);
254    addKey(pos,osgGA::GUIEventAdapter::KEY_F6,"F6",1.0f,F_height);
255    addKey(pos,osgGA::GUIEventAdapter::KEY_F7,"F7",1.0f,F_height);
256    addKey(pos,osgGA::GUIEventAdapter::KEY_F8,"F8",1.0f,F_height);
257    addKey(pos,osgGA::GUIEventAdapter::KEY_F9,"F9",1.0f,F_height);
258    addKey(pos,osgGA::GUIEventAdapter::KEY_F10,"F10",1.0f,F_height);
259    addKey(pos,osgGA::GUIEventAdapter::KEY_F11,"F11",1.0f,F_height);
260    addKey(pos,osgGA::GUIEventAdapter::KEY_F12,"F12",1.0f,F_height);
261
262
263   
264    float cursorMoveHeight=0.35f;
265
266    pos = middle;   
267    addKey(pos,osgGA::GUIEventAdapter::KEY_Left,"Left",1.0f,cursorMoveHeight);
268    osg::Vec3 down = pos;
269    addKey(pos,osgGA::GUIEventAdapter::KEY_Down,"Down",1.0f,cursorMoveHeight);
270    addKey(pos,osgGA::GUIEventAdapter::KEY_Right,"Right",1.0f,cursorMoveHeight);
271   
272    osg::Vec3 keypad = pos;
273    keypad.x()+=1.0f;
274
275    pos = down;
276    pos.z() += 1.0f;
277   
278    addKey(pos,osgGA::GUIEventAdapter::KEY_Up,"Up",1.0f,cursorMoveHeight);
279   
280
281    float homeHeight = 0.35f;
282    pos = middle;
283    pos.z() += 3.0;   
284    addKey(pos,osgGA::GUIEventAdapter::KEY_Delete,"Delete",1.0f,homeHeight);
285    addKey(pos,osgGA::GUIEventAdapter::KEY_End,"End",1.0f,homeHeight);
286    addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Down,"Page\nDown",1.0f,homeHeight);
287   
288    pos = middle;
289    pos.z() += 4.0;   
290    addKey(pos,osgGA::GUIEventAdapter::KEY_Insert,"Insert",1.0f,homeHeight);
291    addKey(pos,osgGA::GUIEventAdapter::KEY_Home,"Home",1.0f,homeHeight);
292    addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Up,"Page\nUp",1.0f,homeHeight);
293
294    pos = middle;
295    pos.z() += 5.5;   
296    addKey(pos,osgGA::GUIEventAdapter::KEY_Print,"PrtScrn\nSysRq",1.0f,homeHeight);
297    addKey(pos,osgGA::GUIEventAdapter::KEY_Scroll_Lock,"ScrLk",1.0f,homeHeight);
298    addKey(pos,osgGA::GUIEventAdapter::KEY_Pause,"Pause\nBreak",1.0f,homeHeight);
299   
300   
301
302    pos = keypad;
303    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Insert,"0",2.0f,1.0f);
304    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Delete,".",1.0f,1.0f);
305    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Enter,"Enter",1.0f,homeHeight);
306   
307    pos = keypad;
308    pos.z() += 1.0f;
309    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_End,"1",1.0f,1.0f);
310    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Down,"2",1.0f,1.0f);
311    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Down,"3",1.0f,1.0f);
312
313    pos = keypad;
314    pos.z() += 2.0f;
315    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Left,"4",1.0f,1.0f);
316    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Begin,"5",1.0f,1.0f);
317    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Right,"6",1.0f,1.0f);
318    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Add,"+",1.0f,1.0f);
319
320    pos = keypad;
321    pos.z() += 3.0f;
322    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Home,"7",1.0f,1.0f);
323    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Up,"8",1.0f,1.0f);
324    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Up,"9",1.0f,1.0f);
325
326    pos = keypad;
327    pos.z() += 4.0f;
328    addKey(pos,osgGA::GUIEventAdapter::KEY_Num_Lock,"Num\nLock",1.0f,0.3f);
329    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Divide,"/",1.0f,1.0f);
330    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Multiply,"*",1.0f,1.0f);
331    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Subtract,"-",1.0f,1.0f);
332   
333    float totalWidth = pos.x()-origin.x();
334    pos = origin;
335    pos.z() += -1.5f;
336
337    osg::Geode* geodeInput = new osg::Geode;
338    {
339        _inputText = new osgText::Text;
340        _inputText->setFont("fonts/arial.ttf");
341        _inputText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
342        _inputText->setCharacterSize(1.0f);
343        _inputText->setMaximumWidth(totalWidth);
344        _inputText->setPosition(pos);
345        _inputText->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
346        _inputText->setAlignment(osgText::Text::BASE_LINE);
347        _inputText->setAxisAlignment(osgText::Text::XZ_PLANE);
348        _inputText->setDataVariance(osg::Object::DYNAMIC);
349        _inputText->setText("Press some keys...");
350       
351        geodeInput->addDrawable(_inputText.get());
352       
353        _scene->addChild(geodeInput);
354    }
355
356}
357
358
359
360
361
362
363class KeyboardEventHandler : public osgGA::GUIEventHandler
364{
365public:
366   
367        KeyboardEventHandler(KeyboardModel* keyboardModel):
368            _keyboardModel(keyboardModel) {}
369   
370        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
371        {
372
373#if 1
374
375//            osg::notify(osg::NOTICE)<<"Mouse "<<ea.getButtonMask()<<std::endl;
376
377            #define PRINT(mask) osg::notify(osg::NOTICE)<<#mask<<" ="<<(ea.getModKeyMask() & mask)<<std::endl;
378            switch(ea.getEventType())
379            {
380                case(osgGA::GUIEventAdapter::KEYDOWN):
381                case(osgGA::GUIEventAdapter::KEYUP):
382                {
383                    osg::notify(osg::NOTICE)<<std::endl;
384                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT);
385                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT);
386                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_ALT);
387                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT);
388                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL);
389                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL);
390                    PRINT(osgGA::GUIEventAdapter::MODKEY_LEFT_META);
391                    PRINT(osgGA::GUIEventAdapter::MODKEY_RIGHT_META);
392                    PRINT(osgGA::GUIEventAdapter::MODKEY_NUM_LOCK);
393                    PRINT(osgGA::GUIEventAdapter::MODKEY_CAPS_LOCK);
394                    break;
395                }
396                default:
397                    break;
398            }
399#endif
400            switch(ea.getEventType())
401            {
402                case(osgGA::GUIEventAdapter::KEYDOWN):
403                {
404                    _keyboardModel->keyChange(ea.getKey(),1);
405                    return true;
406                }
407                case(osgGA::GUIEventAdapter::KEYUP):
408                {
409                    _keyboardModel->keyChange(ea.getKey(),0);
410                    return true;
411                }
412
413                default:
414                    return false;
415            }
416        }
417       
418        osg::ref_ptr<KeyboardModel> _keyboardModel;
419       
420};
421
422int main(int , char **)
423{
424    osgViewer::Viewer viewer;
425
426    osg::ref_ptr<KeyboardModel> keyboardModel = new KeyboardModel;
427
428    viewer.addEventHandler(new osgViewer::StatsHandler);
429    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
430    viewer.addEventHandler(new KeyboardEventHandler(keyboardModel.get()));
431    viewer.setSceneData( keyboardModel->getScene() );
432
433    return viewer.run();
434}
Note: See TracBrowser for help on using the browser.