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

Revision 1750, 14.7 kB (checked in by robert, 11 years ago)

Added text input field to the osgkeyboard demo.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osgProducer/Viewer>
2
3#include <osg/MatrixTransform>
4#include <osg/Geode>
5#include <osg/Group>
6#include <osg/Switch>
7#include <osg/Notify>
8#include <osg/Geometry>
9
10#include <osgText/Text>
11
12#include <osgDB/Registry>
13#include <osgDB/ReadFile>
14#include <osgDB/WriteFile>
15
16
17class KeyboardModel : public osg::Referenced
18{
19public:
20
21        KeyboardModel() { createKeyboard(); }
22       
23        osg::Group* getScene() { return _scene.get(); }
24       
25        void keyChange(int key,int value);
26       
27protected:
28       
29        ~KeyboardModel() {}
30
31        osg::Switch* addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height);
32        osg::Switch* addKey(int key,osg::Switch* sw);
33
34        void createKeyboard();
35
36        typedef std::map<int, osg::ref_ptr<osg::Switch> > KeyModelMap;
37       
38        osg::ref_ptr<osg::Group>    _scene;
39        KeyModelMap                 _keyModelMap;
40        osg::ref_ptr<osgText::Text> _inputText;
41
42};
43
44void KeyboardModel::keyChange(int key,int value)
45{
46    std::cout << "key value change, code="<<std::hex << key << "\t value="<< value << std::dec  << std::endl;
47
48    // toggle the keys graphical representation on or off via osg::Swithc
49    KeyModelMap::iterator itr = _keyModelMap.find(key);
50    if (itr!=_keyModelMap.end())
51    {
52        itr->second->setSingleChildOn(value);
53    }
54   
55    if (value)
56    {
57        // when a key is pressed add the new data to the text field
58       
59        if (key>0 && key<256)
60        {
61            // just add ascii characters right now...
62            _inputText->getText().push_back(key);
63            _inputText->update();
64        }
65        else if (key==osgGA::GUIEventAdapter::KEY_Return)
66        {
67            _inputText->getText().push_back('\n');
68            _inputText->update();
69        }
70        else if (key==osgGA::GUIEventAdapter::KEY_BackSpace || key==osgGA::GUIEventAdapter::KEY_Delete)
71        {
72            if (!_inputText->getText().empty())
73            {
74                _inputText->getText().pop_back();
75                _inputText->update();
76            }
77        }
78       
79    }
80   
81}
82
83osg::Switch* KeyboardModel::addKey(osg::Vec3& pos, int key,const std::string& text,float width, float height)
84{
85
86    osg::Geode* geodeUp = new osg::Geode;
87    {
88        osgText::Text* textUp = new osgText::Text;
89        textUp->setFont("fonts/arial.ttf");
90        textUp->setColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
91        textUp->setCharacterSize(height);
92        textUp->setPosition(pos);
93        textUp->setDrawMode(osgText::Text::TEXT/*|osgText::Text::BOUNDINGBOX*/);
94        textUp->setAlignment(osgText::Text::LEFT_CENTER);
95        textUp->setAxisAlignment(osgText::Text::XZ_PLANE);
96        textUp->setText(text);
97       
98        geodeUp->addDrawable(textUp);
99    }
100   
101    osg::Geode* geodeDown = new osg::Geode;
102    {
103        osgText::Text* textDown = new osgText::Text;
104        textDown->setFont("fonts/arial.ttf");
105        textDown->setColor(osg::Vec4(1.0f,0.0f,1.0f,1.0f));
106        textDown->setCharacterSize(height);
107        textDown->setPosition(pos);
108        textDown->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
109        textDown->setAlignment(osgText::Text::LEFT_CENTER);
110        textDown->setAxisAlignment(osgText::Text::XZ_PLANE);
111        textDown->setText(text);
112       
113        geodeDown->addDrawable(textDown);
114    }
115
116    osg::Switch* model = new osg::Switch;
117    model->addChild(geodeUp,true);
118    model->addChild(geodeDown,false);
119   
120    _scene->addChild(model);
121
122    _keyModelMap[key] = model;
123   
124    pos.x() += width;
125   
126    return model;
127   
128}
129
130osg::Switch* KeyboardModel::addKey(int key,osg::Switch* sw)
131{
132    _keyModelMap[key] = sw;
133    return sw;
134}
135
136void KeyboardModel::createKeyboard()
137{
138    _scene = new osg::Group;
139   
140    osg::Vec3 origin(0.0f,0.0f,0.0f);
141    osg::Vec3 pos=origin;
142   
143    addKey(pos,osgGA::GUIEventAdapter::KEY_Control_L,"Ctrl",2.0f,0.5f);
144    addKey(pos,osgGA::GUIEventAdapter::KEY_Super_L,"Super",2.0f,0.5f);
145    addKey(pos,osgGA::GUIEventAdapter::KEY_Alt_L,"Alt",2.0f,0.5f);
146    addKey(pos,osgGA::GUIEventAdapter::KEY_Space,"Space",3.0f,1.0f);
147    addKey(pos,osgGA::GUIEventAdapter::KEY_Mode_switch,"Switch",2.0f,0.5f);
148    addKey(pos,osgGA::GUIEventAdapter::KEY_Super_R,"Super",2.0f,0.5f);
149    addKey(pos,osgGA::GUIEventAdapter::KEY_Menu,"Menu",2.0f,0.5f);
150    addKey(pos,osgGA::GUIEventAdapter::KEY_Control_R,"Ctrl",2.0f,0.5f);
151
152    osg::Vec3 middle(pos.x()+1.0f,0.0f,0.0f);
153   
154    pos.x() = 0.0f;
155    pos.z() += 1.0f;
156
157    addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_L,"Shift",2.0f,0.5f);
158    addKey(pos,'\\',"\\",1.0f,1.0f);
159    addKey('Z',addKey(pos,'z',"Z",1.0f,1.0f));
160    addKey('X',addKey(pos,'x',"X",1.0f,1.0f));
161    addKey('C',addKey(pos,'c',"C",1.0f,1.0f));
162    addKey('V',addKey(pos,'v',"V",1.0f,1.0f));
163    addKey('B',addKey(pos,'b',"B",1.0f,1.0f));
164    addKey('N',addKey(pos,'n',"N",1.0f,1.0f));
165    addKey('M',addKey(pos,'m',"M",1.0f,1.0f));
166    addKey('<',addKey(pos,',',",",1.0f,1.0f));
167    addKey('>',addKey(pos,'.',".",1.0f,1.0f));
168    addKey('?',addKey(pos,'/',"/",1.0f,1.0f));
169    addKey(pos,osgGA::GUIEventAdapter::KEY_Shift_R,"Shift",2.0f,0.5f);
170
171    pos.x() = 0.0f;
172    pos.z() += 1.0f;
173   
174    addKey(pos,osgGA::GUIEventAdapter::KEY_Caps_Lock,"Caps",2.0f,0.5f);
175    addKey('A',addKey(pos,'a',"A",1.0f,1.0f));
176    addKey('S',addKey(pos,'s',"S",1.0f,1.0f));
177    addKey('D',addKey(pos,'d',"D",1.0f,1.0f));
178    addKey('F',addKey(pos,'f',"F",1.0f,1.0f));
179    addKey('G',addKey(pos,'g',"G",1.0f,1.0f));
180    addKey('H',addKey(pos,'h',"H",1.0f,1.0f));
181    addKey('J',addKey(pos,'j',"J",1.0f,1.0f));
182    addKey('K',addKey(pos,'k',"K",1.0f,1.0f));
183    addKey('L',addKey(pos,'l',"L",1.0f,1.0f));
184    addKey(':',addKey(pos,';',";",1.0f,1.0f));
185    addKey('@',addKey(pos,'\'',"'",1.0f,1.0f));
186    addKey('~',addKey(pos,'#',"#",1.0f,1.0f));
187    addKey(pos,osgGA::GUIEventAdapter::KEY_Return,"Return",4.0f,0.5f);
188
189    pos.x() = 0.0f;
190    pos.z() += 1.0f;
191   
192    addKey(pos,osgGA::GUIEventAdapter::KEY_Tab,"Tab",2.0f,0.5f);
193    addKey('Q',addKey(pos,'q',"Q",1.0f,1.0f));
194    addKey('W',addKey(pos,'w',"W",1.0f,1.0f));
195    addKey('E',addKey(pos,'e',"E",1.0f,1.0f));
196    addKey('R',addKey(pos,'r',"R",1.0f,1.0f));
197    addKey('T',addKey(pos,'t',"T",1.0f,1.0f));
198    addKey('Y',addKey(pos,'y',"Y",1.0f,1.0f));
199    addKey('U',addKey(pos,'u',"U",1.0f,1.0f));
200    addKey('I',addKey(pos,'i',"I",1.0f,1.0f));
201    addKey('O',addKey(pos,'o',"O",1.0f,1.0f));
202    addKey('P',addKey(pos,'p',"P",1.0f,1.0f));
203    addKey('{',addKey(pos,'[',"[",1.0f,1.0f));
204    addKey('}',addKey(pos,']',"]",1.0f,1.0f));
205
206    pos.x() = 0.0f;
207    pos.z() += 1.0f;
208   
209    addKey(pos,'`',"`",1.0f,1.0f);
210    addKey(pos,'1',"1",1.0f,1.0f);
211    addKey(pos,'2',"2",1.0f,1.0f);
212    addKey(pos,'3',"3",1.0f,1.0f);
213    addKey(pos,'4',"4",1.0f,1.0f);
214    addKey(pos,'5',"5",1.0f,1.0f);
215    addKey(pos,'6',"6",1.0f,1.0f);
216    addKey(pos,'7',"7",1.0f,1.0f);
217    addKey(pos,'8',"8",1.0f,1.0f);
218    addKey(pos,'9',"9",1.0f,1.0f);
219    addKey(pos,'0',"0",1.0f,1.0f);
220    addKey(pos,'-',"-",1.0f,1.0f);
221    addKey(pos,'=',"=",1.0f,1.0f);
222    addKey(pos,osgGA::GUIEventAdapter::KEY_BackSpace,"Backspace",3.0f,0.5f);
223
224    pos.x() = 0.0f;
225    pos.z() += 1.5f;
226   
227    float F_height = 0.5f;
228    addKey(pos,osgGA::GUIEventAdapter::KEY_Escape,"Esc",2.0f,F_height);
229    addKey(pos,osgGA::GUIEventAdapter::KEY_F1,"F1",1.0f,F_height);
230    addKey(pos,osgGA::GUIEventAdapter::KEY_F2,"F2",1.0f,F_height);
231    addKey(pos,osgGA::GUIEventAdapter::KEY_F3,"F3",1.0f,F_height);
232    addKey(pos,osgGA::GUIEventAdapter::KEY_F4,"F4",1.0f,F_height);
233    addKey(pos,osgGA::GUIEventAdapter::KEY_F5,"F5",1.0f,F_height);
234    addKey(pos,osgGA::GUIEventAdapter::KEY_F6,"F6",1.0f,F_height);
235    addKey(pos,osgGA::GUIEventAdapter::KEY_F7,"F7",1.0f,F_height);
236    addKey(pos,osgGA::GUIEventAdapter::KEY_F8,"F8",1.0f,F_height);
237    addKey(pos,osgGA::GUIEventAdapter::KEY_F9,"F9",1.0f,F_height);
238    addKey(pos,osgGA::GUIEventAdapter::KEY_F10,"F10",1.0f,F_height);
239    addKey(pos,osgGA::GUIEventAdapter::KEY_F11,"F11",1.0f,F_height);
240    addKey(pos,osgGA::GUIEventAdapter::KEY_F12,"F12",1.0f,F_height);
241
242
243   
244    float cursorMoveHeight=0.35f;
245
246    pos = middle;   
247    addKey(pos,osgGA::GUIEventAdapter::KEY_Left,"Left",1.0f,cursorMoveHeight);
248    osg::Vec3 down = pos;
249    addKey(pos,osgGA::GUIEventAdapter::KEY_Down,"Down",1.0f,cursorMoveHeight);
250    addKey(pos,osgGA::GUIEventAdapter::KEY_Right,"Right",1.0f,cursorMoveHeight);
251   
252    osg::Vec3 keypad = pos;
253    keypad.x()+=1.0f;
254
255    pos = down;
256    pos.z() += 1.0f;
257   
258    addKey(pos,osgGA::GUIEventAdapter::KEY_Up,"Up",1.0f,cursorMoveHeight);
259   
260
261    float homeHeight = 0.35f;
262    pos = middle;
263    pos.z() += 3.0;   
264    addKey(pos,osgGA::GUIEventAdapter::KEY_Delete,"Delete",1.0f,homeHeight);
265    addKey(pos,osgGA::GUIEventAdapter::KEY_End,"End",1.0f,homeHeight);
266    addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Down,"Page\nDown",1.0f,homeHeight);
267   
268    pos = middle;
269    pos.z() += 4.0;   
270    addKey(pos,osgGA::GUIEventAdapter::KEY_Insert,"Insert",1.0f,homeHeight);
271    addKey(pos,osgGA::GUIEventAdapter::KEY_Home,"Home",1.0f,homeHeight);
272    addKey(pos,osgGA::GUIEventAdapter::KEY_Page_Up,"Page\nUp",1.0f,homeHeight);
273
274    pos = middle;
275    pos.z() += 5.5;   
276    addKey(pos,osgGA::GUIEventAdapter::KEY_Print,"PrtScrn\nSysRq",1.0f,homeHeight);
277    addKey(pos,osgGA::GUIEventAdapter::KEY_Scroll_Lock,"ScrLk",1.0f,homeHeight);
278    addKey(pos,osgGA::GUIEventAdapter::KEY_Pause,"Pause\nBreak",1.0f,homeHeight);
279   
280   
281
282    pos = keypad;
283    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Insert,"0",2.0f,1.0f);
284    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Delete,".",1.0f,1.0f);
285    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Enter,"Enter",1.0f,homeHeight);
286   
287    pos = keypad;
288    pos.z() += 1.0f;
289    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_End,"1",1.0f,1.0f);
290    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Down,"2",1.0f,1.0f);
291    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Down,"3",1.0f,1.0f);
292
293    pos = keypad;
294    pos.z() += 2.0f;
295    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Left,"4",1.0f,1.0f);
296    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Begin,"5",1.0f,1.0f);
297    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Right,"6",1.0f,1.0f);
298    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Add,"+",1.0f,1.0f);
299
300    pos = keypad;
301    pos.z() += 3.0f;
302    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Home,"7",1.0f,1.0f);
303    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Up,"8",1.0f,1.0f);
304    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Page_Up,"9",1.0f,1.0f);
305
306    pos = keypad;
307    pos.z() += 4.0f;
308    addKey(pos,osgGA::GUIEventAdapter::KEY_Num_Lock,"Num\nLock",1.0f,0.3f);
309    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Divide,"/",1.0f,1.0f);
310    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Multiply,"*",1.0f,1.0f);
311    addKey(pos,osgGA::GUIEventAdapter::KEY_KP_Subtract,"-",1.0f,1.0f);
312   
313    float totalWidth = pos.x()-origin.x();
314    pos = origin;
315    pos.z() += -1.5f;
316
317    osg::Geode* geodeInput = new osg::Geode;
318    {
319        _inputText = new osgText::Text;
320        _inputText->setFont("fonts/arial.ttf");
321        _inputText->setColor(osg::Vec4(1.0f,1.0f,0.0f,1.0f));
322        _inputText->setCharacterSize(1.0f);
323        _inputText->setMaximumWidth(totalWidth);
324        _inputText->setPosition(pos);
325        _inputText->setDrawMode(osgText::Text::TEXT/*||osgText::Text::BOUNDINGBOX*/);
326        _inputText->setAlignment(osgText::Text::BASE_LINE);
327        _inputText->setAxisAlignment(osgText::Text::XZ_PLANE);
328        _inputText->setText("Press some keys...");
329       
330        geodeInput->addDrawable(_inputText.get());
331       
332        _scene->addChild(geodeInput);
333    }
334
335}
336
337
338
339
340
341class KeyboardEventHandler : public osgGA::GUIEventHandler
342{
343public:
344   
345        KeyboardEventHandler(KeyboardModel* keyboardModel):
346            _keyboardModel(keyboardModel) {}
347   
348        virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
349        {
350            switch(ea.getEventType())
351            {
352                case(osgGA::GUIEventAdapter::KEYDOWN):
353                {
354                    _keyboardModel->keyChange(ea.getKey(),1);
355                    return true;
356                }
357                case(osgGA::GUIEventAdapter::KEYUP):
358                {
359                    _keyboardModel->keyChange(ea.getKey(),0);
360                    return true;
361                }
362
363                default:
364                    return false;
365            }
366        }
367
368        virtual void accept(osgGA::GUIEventHandlerVisitor& v)
369        {
370            v.visit(*this);
371        }
372       
373        osg::ref_ptr<KeyboardModel> _keyboardModel;
374       
375};
376
377int main( int argc, char **argv )
378{
379
380    // use an ArgumentParser object to manage the program arguments.
381    osg::ArgumentParser arguments(&argc,argv);
382
383    // set up the usage document, in case we need to print out how to use this program.
384    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getProgramName()+" [options] filename ...");
385    arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
386    arguments.getApplicationUsage()->addCommandLineOption("-c","Mannually create occluders");
387   
388    // initialize the viewer.
389    osgProducer::Viewer viewer(arguments);
390
391    // set up the value with sensible default event handlers.
392    viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
393
394
395    osg::ref_ptr<KeyboardModel> keyboardModel = new KeyboardModel;
396
397    KeyboardEventHandler* keh = new KeyboardEventHandler(keyboardModel.get());
398    viewer.getEventHandlerList().push_front(keh);
399
400    // get details on keyboard and mouse bindings used by the viewer.
401    viewer.getUsage(*arguments.getApplicationUsage());
402
403    // if user request help write it out to cout.
404    if (arguments.read("-h") || arguments.read("--help"))
405    {
406        arguments.getApplicationUsage()->write(std::cout);
407        return 1;
408    }
409
410    // any option left unread are converted into errors to write out later.
411    arguments.reportRemainingOptionsAsUnrecognized();
412
413    // report any errors if they have occured when parsing the program aguments.
414    if (arguments.errors())
415    {
416        arguments.writeErrorMessages(std::cout);
417        return 1;
418    }
419
420     
421    // attach the scene graph.
422    viewer.setSceneData( keyboardModel->getScene() );
423
424    osgDB::writeNodeFile(*keyboardModel->getScene(),"test.osg");
425
426
427    // create the windows and run the threads.
428    viewer.realize(Producer::CameraGroup::ThreadPerCamera);
429
430
431    while( !viewer.done() )
432    {
433        // wait for all cull and draw threads to complete.
434        viewer.sync();
435
436        // update the scene by traversing it with the the update visitor which will
437        // call all node update callbacks and animations.
438        viewer.update();
439         
440        // fire off the cull and draw traversals of the scene.
441        viewer.frame();
442       
443    }
444   
445    // wait for all cull and draw threads to complete before exit.
446    viewer.sync();
447
448    return 0;
449}
Note: See TracBrowser for help on using the browser.