root/OpenSceneGraph/trunk/examples/osgviewerWX/osgviewerWX.cpp @ 8350

Revision 8350, 7.1 kB (checked in by robert, 7 years ago)

From Paul Melis, "Here is an update to the osgviewerWX example. Keyboard events were not always received because the GraphicsWindowWX wasn't receiving focus. It now receives focus when the mouse enters the window.
* I split the mouse handling from a monolithic method to separate ones, slightly cleaner than a whole bunch of if()'s, especially with another case of the mouse entering the canvas.
* I changed the EVT_KEY_DOWN handler to an EVT_CHAR handler, although that now makes the up and down handler assymetric. The new down-handler returns translated key codes, so when you press the S key (without anything else), it actually returns 's' and not 'S' as the EVT_KEY_DOWN did. This means that statistics can be called up in the viewer window, while the example previously only printed a "Stats output:" line to the console. I'm not truly happy that the up handler returns _untranslated_ key codes. But solving this completely would probably mean adding some table that translated from wxWidgets' untranslated key codes to OSG's internal ones. This might be interesting to add, as anyone using OSG + wxWidgets in any serious manner would also have to add this.
* I commented out the evt.Skip()'s in the keyboard handlers as these would only be necessary if there were some key events that are not handled. But currently all key events are simply forwarded.
* I changed the handling of a mouse drag to a more general mouse move"

Line 
1// For compilers that support precompilation, includes "wx.h".
2#include "wx/wxprec.h"
3
4#ifdef __BORLANDC__
5#pragma hdrstop
6#endif
7
8#ifndef WX_PRECOMP
9#include "wx/wx.h"
10#endif
11
12#include "osgviewerWX.h"
13
14
15#include <osgViewer/ViewerEventHandlers>
16#include <osgGA/TrackballManipulator>
17#include <osgDB/ReadFile>
18#include <wx/image.h>
19#include <wx/menu.h>
20
21#include <iostream>
22
23// `Main program' equivalent, creating windows and returning main app frame
24bool wxOsgApp::OnInit()
25{
26    if (argc<2)
27    {
28        std::cout << wxString(argv[0]).mb_str() <<": requires filename argument." << std::endl;
29        return false;
30    }
31
32    int width = 800;
33    int height = 600;
34
35    // Create the main frame window
36
37    MainFrame *frame = new MainFrame(NULL, wxT("wxWidgets OSG Sample"),
38        wxDefaultPosition, wxSize(width, height));
39
40    // create osg canvas
41    //    - initialize
42
43    int *attributes = new int[6];
44    attributes[0] = int(WX_GL_DOUBLEBUFFER);
45    attributes[1] = WX_GL_RGBA;
46    attributes[2] = WX_GL_DEPTH_SIZE;
47    attributes[3] = 8;
48    attributes[4] = WX_GL_STENCIL_SIZE;
49    attributes[5] = 8;
50
51    GraphicsWindowWX* gw = new GraphicsWindowWX(frame, wxID_ANY, wxDefaultPosition,
52                                                wxSize(width, height), wxSUNKEN_BORDER, wxT("osgviewerWX"), attributes);
53
54    osgViewer::Viewer *viewer = new osgViewer::Viewer;
55    viewer->getCamera()->setGraphicsContext(gw);
56    viewer->getCamera()->setViewport(0,0,width,height);
57    viewer->addEventHandler(new osgViewer::StatsHandler);
58    viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
59
60    // load the scene.
61    wxString fname(argv[1]);
62    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(std::string(fname.mb_str()));
63    if (!loadedModel)
64    {
65        std::cout << argv[0] <<": No data loaded." << std::endl;
66        return false;
67    }
68
69    viewer->setSceneData(loadedModel.get());
70    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
71    frame->SetViewer(viewer);
72
73    /* Show the frame */
74    frame->Show(true);
75
76    return true;
77}
78
79IMPLEMENT_APP(wxOsgApp)
80
81BEGIN_EVENT_TABLE(MainFrame, wxFrame)
82    EVT_IDLE(MainFrame::OnIdle)
83END_EVENT_TABLE()
84
85/* My frame constructor */
86MainFrame::MainFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
87    const wxSize& size, long style)
88    : wxFrame(frame, wxID_ANY, title, pos, size, style)
89{
90}
91
92void MainFrame::SetViewer(osgViewer::Viewer *viewer)
93{
94    _viewer = viewer;
95}
96
97void MainFrame::OnIdle(wxIdleEvent &event)
98{
99    _viewer->frame();
100
101    event.RequestMore();
102}
103
104BEGIN_EVENT_TABLE(GraphicsWindowWX, wxGLCanvas)
105    EVT_SIZE                (GraphicsWindowWX::OnSize)
106    EVT_PAINT               (GraphicsWindowWX::OnPaint)
107    EVT_ERASE_BACKGROUND    (GraphicsWindowWX::OnEraseBackground)
108
109    EVT_CHAR                (GraphicsWindowWX::OnChar)
110    EVT_KEY_UP              (GraphicsWindowWX::OnKeyUp)
111
112    EVT_ENTER_WINDOW    (GraphicsWindowWX::OnMouseEnter)
113    EVT_LEFT_DOWN       (GraphicsWindowWX::OnMouseDown)
114    EVT_MIDDLE_DOWN     (GraphicsWindowWX::OnMouseDown)
115    EVT_RIGHT_DOWN      (GraphicsWindowWX::OnMouseDown)
116    EVT_LEFT_UP         (GraphicsWindowWX::OnMouseUp)
117    EVT_MIDDLE_UP       (GraphicsWindowWX::OnMouseUp)
118    EVT_RIGHT_UP        (GraphicsWindowWX::OnMouseUp)
119    EVT_MOTION          (GraphicsWindowWX::OnMouseMotion)
120END_EVENT_TABLE()
121
122GraphicsWindowWX::GraphicsWindowWX(wxWindow *parent, wxWindowID id,
123    const wxPoint& pos, const wxSize& size, long style, const wxString& name, int *attributes)
124    : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, attributes)
125{
126    // default cursor to standard
127    _oldCursor = *wxSTANDARD_CURSOR;
128
129    _traits = new GraphicsContext::Traits;
130    _traits->x = pos.x;
131    _traits->y = pos.y;
132    _traits->width = size.x;
133    _traits->height = size.y;
134
135    init();
136
137}
138
139void GraphicsWindowWX::init()
140{
141    if (valid())
142    {
143        setState( new osg::State );
144        getState()->setGraphicsContext(this);
145
146        if (_traits.valid() && _traits->sharedContext)
147        {
148            getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
149            incrementContextIDUsageCount( getState()->getContextID() );
150        }
151        else
152        {
153            getState()->setContextID( osg::GraphicsContext::createNewContextID() );
154        }
155    }
156}
157
158GraphicsWindowWX::~GraphicsWindowWX()
159{
160}
161
162void GraphicsWindowWX::OnPaint( wxPaintEvent& WXUNUSED(event) )
163{
164    /* must always be here */
165    wxPaintDC dc(this);
166}
167
168void GraphicsWindowWX::OnSize(wxSizeEvent& event)
169{
170    // this is also necessary to update the context on some platforms
171    wxGLCanvas::OnSize(event);
172
173    // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
174    int width, height;
175    GetClientSize(&width, &height);
176
177    // update the window dimensions, in case the window has been resized.
178    getEventQueue()->windowResize(0, 0, width, height);
179    resized(0,0,width,height);
180}
181
182void GraphicsWindowWX::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
183{
184    /* Do nothing, to avoid flashing on MSW */
185}
186
187void GraphicsWindowWX::OnChar(wxKeyEvent &event)
188{
189#if wxUSE_UNICODE
190    int key = event.GetUnicodeKey();
191#else
192    int key = event.GetKeyCode();
193#endif
194    getEventQueue()->keyPress(key);
195
196    // If this key event is not processed here, we should call
197    // event.Skip() to allow processing to continue.
198}
199
200void GraphicsWindowWX::OnKeyUp(wxKeyEvent &event)
201{
202#if wxUSE_UNICODE
203    int key = event.GetUnicodeKey();
204#else
205    int key = event.GetKeyCode();
206#endif
207    getEventQueue()->keyRelease(key);
208
209    // If this key event is not processed here, we should call
210    // event.Skip() to allow processing to continue.
211}
212
213void GraphicsWindowWX::OnMouseEnter(wxMouseEvent &event)
214{
215    // Set focus to ourselves, so keyboard events get directed to us
216    SetFocus();
217}
218
219void GraphicsWindowWX::OnMouseDown(wxMouseEvent &event)
220{
221    getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(),
222        event.GetButton());
223}
224
225void GraphicsWindowWX::OnMouseUp(wxMouseEvent &event)
226{
227    getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(),
228        event.GetButton());
229}
230
231void GraphicsWindowWX::OnMouseMotion(wxMouseEvent &event)
232{
233    getEventQueue()->mouseMotion(event.GetX(), event.GetY());
234}
235
236
237void GraphicsWindowWX::grabFocus()
238{
239    // focus this window
240    SetFocus();
241}
242
243void GraphicsWindowWX::grabFocusIfPointerInWindow()
244{
245    // focus this window, if the pointer is in the window
246    wxPoint pos = wxGetMousePosition();
247    if (this == wxFindWindowAtPoint(pos)) {
248        SetFocus();
249    }
250}
251
252void GraphicsWindowWX::useCursor(bool cursorOn)
253{
254    if (cursorOn) {
255
256        // show the old cursor
257        SetCursor(_oldCursor);
258    }
259    else {
260
261        // remember the old cursor
262        _oldCursor = GetCursor();
263
264        // hide the cursor
265        //    - can't find a way to do this neatly, so create a 1x1, transparent image
266        wxImage image(1,1);
267        image.SetMask(true);
268        image.SetMaskColour(0, 0, 0);
269        wxCursor cursor(image);
270        SetCursor(cursor);
271    }
272}
273
274bool GraphicsWindowWX::makeCurrentImplementation()
275{
276    SetCurrent();
277    return true;
278}
279
280void GraphicsWindowWX::swapBuffersImplementation()
281{
282    SwapBuffers();
283}
Note: See TracBrowser for help on using the browser.