root/OpenSceneGraph/trunk/include/osgWidget/WindowManager @ 13041

Revision 13041, 11.9 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14// Code by: Jeremy Moles (cubicool) 2007-2008
15
16#ifndef OSGWIDGET_WINDOW_MANAGER
17#define OSGWIDGET_WINDOW_MANAGER
18
19#include <osg/Switch>
20#include <osg/Uniform>
21#include <osg/Drawable>
22#include <osgGA/GUIEventAdapter>
23#include <osgUtil/LineSegmentIntersector>
24#include <osgViewer/View>
25#include <osgWidget/ScriptEngine>
26#include <osgWidget/StyleManager>
27#include <osgWidget/Window>
28
29namespace osgWidget {
30
31// TODO: It should be possible to use something other than osgWidget/ViewerEventHandlers
32// to handle all of these events. In fact, I need to create an SDL example showing this.
33
34// A private typedef that we use for pickAtXY() below.
35typedef osgUtil::LineSegmentIntersector::Intersections Intersections;
36
37// A WindowManager performs pointer interaction with the topmost (highest Z) Widget,
38// and performs keyboard input on the currently focused Window->Widget.
39class OSGWIDGET_EXPORT WindowManager: public osg::Switch, public UIObjectParent<Window> {
40    public:
41        enum WmFlags {
42            WM_USE_LUA        = 0x00000001,
43            WM_USE_PYTHON     = 0x00000002,
44            WM_USE_RENDERBINS = 0x00000004,
45            WM_PICK_DEBUG     = 0x00000008
46        };
47
48        enum PointerDirection {
49            PD_NONE  = 0x00000000,
50            PD_LEFT  = 0x00000001,
51            PD_RIGHT = 0x00000002,
52            PD_UP    = 0x00000004,
53            PD_DOWN  = 0x00000008
54        };
55
56        enum PointerFocusMode {
57            PFM_FOCUS   = 0x00000000,
58            PFM_UNFOCUS = 0x00000001,
59            PFM_SLOPPY  = 0x00000002
60        };
61
62    public:
63        META_Object(osgWidget, WindowManager);
64
65        WindowManager(
66            osgViewer::View* = 0,
67            point_type       = 0.0f,
68            point_type       = 0.0f,
69            unsigned int     = 0,
70            unsigned int     = 0
71        );
72
73        WindowManager(const WindowManager&, const osg::CopyOp&);
74
75        virtual ~WindowManager();
76
77        // A static method that will set both the _widget and _window data of an Event
78        // reference from a passed-in Interface.
79        static void setEventFromInterface(Event&, EventInterface*);
80
81        // A static template method that will iterate over a container and return a
82        // properly formed EventInterface*.
83        template<typename T>
84        static EventInterface* getFirstEventInterface(T&, Event&);
85
86        bool pickAtXY         (float, float, WidgetList&);
87        bool setFocused       (Window*);
88        void setPointerXY     (float, float);
89        void setStyleManager  (StyleManager*);
90        void resizeAllWindows (bool = true);
91
92        XYCoord windowXY (double, double) const;
93        XYCoord localXY  (double, double) const;
94
95        // Methods all called by the ViewerEventHandlers::MouseHandler object, or
96        // by some customer caller of your own. Examples of this to come...
97        bool pointerMove (float, float);
98        bool pointerDrag (float, float);
99        bool mouseScroll (float, float);
100
101        osg::Camera* createParentOrthoCamera();
102
103        unsigned int getNodeMask() const {
104            return _nodeMask;
105        }
106
107        point_type getWidth() const {
108            return _width;
109        }
110
111        point_type getHeight() const {
112            return _height;
113        }
114
115        bool isUsingLua() const {
116            return (_flags & WM_USE_LUA) != 0;
117        }
118
119        bool isUsingPython() const {
120            return (_flags & WM_USE_PYTHON) != 0;
121        }
122
123        bool isUsingRenderBins() const {
124            return (_flags & WM_USE_RENDERBINS) != 0;
125        }
126
127        int getMouseKeysDown() const {
128            int flag = 0;
129
130            flag |= _leftDown ? osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON : 0;
131            flag |= _middleDown ? osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON: 0;
132            flag |= _rightDown ? osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON : 0;
133
134            return flag;
135        }
136
137        ScriptEngine* getLuaEngine() {
138            return _lua.get();
139        }
140
141        const ScriptEngine* getLuaEngine() const {
142            return _lua.get();
143        }
144
145        ScriptEngine* getPythonEngine() {
146            return _python.get();
147        }
148
149        const ScriptEngine* getPythonEngine() const {
150            return _python.get();
151        }
152
153        StyleManager* getStyleManager() {
154            return _styleManager.get();
155        }
156
157        const StyleManager* getStyleManager() const {
158            return _styleManager.get();
159        }
160
161        PointerDirection getPointerVerticalDirection() const {
162            return _lastVertical;
163        }
164
165        PointerDirection getPointerHorizontalDirection() const {
166            return _lastHorizontal;
167        }
168
169        PointerFocusMode getPointerFocusMode() const {
170            return _focusMode;
171        }
172
173        int getPointerDirectionVector() const {
174            return _lastVertical | _lastHorizontal;
175        }
176
177        bool isPointerMovingUp() const {
178            return _lastVertical == PD_UP;
179        }
180
181        bool isPointerMovingDown() const {
182            return _lastVertical == PD_DOWN;
183        }
184
185        bool isPointerMovingLeft() const {
186            return _lastHorizontal == PD_LEFT;
187        }
188
189        bool isPointerMovingRight() const {
190            return _lastHorizontal == PD_RIGHT;
191        }
192
193        bool isPointerMovingVertically() const {
194            return _lastVertical != PD_NONE;
195        }
196
197        bool isPointerMovingHorizontally() const {
198            return _lastHorizontal != PD_NONE;
199        }
200
201        bool isLeftMouseButtonDown() const {
202            return _leftDown;
203        }
204
205        bool isMiddleMouseButtonDown() const {
206            return _middleDown;
207        }
208
209        bool isRightMouseButtonDown() const {
210            return _rightDown;
211        }
212
213        bool isMouseScrollingUp() const {
214            return _scrolling == osgGA::GUIEventAdapter::SCROLL_UP;
215        }
216
217        bool isMouseScrollingDown() const {
218            return _scrolling == osgGA::GUIEventAdapter::SCROLL_DOWN;
219        }
220
221        bool setFocusedByName(const std::string& name) {
222            return setFocused(getByName(name));
223        }
224
225        void setScrollingMotion(osgGA::GUIEventAdapter::ScrollingMotion sm) {
226            _scrolling = sm;
227        }
228
229        void setPointerFocusMode(PointerFocusMode pfm) {
230            _focusMode = pfm;
231        }
232
233        void setWidth(point_type w) {
234            _width = w;
235        }
236
237        void setHeight(point_type h) {
238            _height = h;
239        }
240
241        void setSize(point_type w, point_type h) {
242            _width  = w;
243            _height = h;
244        }
245
246        void setWindowSize(point_type w, point_type h) {
247            _windowWidth  = w;
248            _windowHeight = h;
249        }
250
251        // Wrappers around the real calls. These only pertains to mouse buttons,
252        // particularly 3-button mice, although there are other more generic
253        // "pointer" API methods.
254        bool mousePushedLeft(float x, float y) {
255            return _handleMousePushed(x, y, _leftDown);
256        }
257
258        bool mousePushedMiddle(float x, float y) {
259            return _handleMousePushed(x, y, _middleDown);
260        }
261
262        bool mousePushedRight(float x, float y) {
263            return _handleMousePushed(x, y, _rightDown);
264        }
265
266        bool mouseReleasedLeft(float x, float y) {
267            return _handleMouseReleased(x, y, _leftDown);
268        }
269
270        bool mouseReleasedMiddle(float x, float y) {
271            return _handleMouseReleased(x, y, _middleDown);
272        }
273
274        bool mouseReleasedRight(float x, float y) {
275            return _handleMouseReleased(x, y, _rightDown);
276        }
277
278        // Keyboards wrappers, as above; takes the key and key's mask code, which
279        // can be compared to osgGA::GUIEventAdapter::{KeySymbol,KeyModMask}.
280        bool keyDown (int, int);
281        bool keyUp   (int, int);
282
283        osgViewer::View* getView() { return _view; }
284        const osgViewer::View* getView() const { return _view; }
285
286    private:
287        // A functor used to sort the Windows by their Z component in descending order.
288        struct WindowZCompare: public std::binary_function<ptr_type, ptr_type, bool> {
289            bool operator()(const ptr_type& x, const ptr_type& y) {
290                return x.get()->getZ() > y.get()->getZ();
291            }
292        };
293
294        // A functor used to sort the Windows by their BinNum component in descending order.
295        struct WindowBinNumberCompare: public std::binary_function<ptr_type, ptr_type, bool> {
296            bool operator()(const ptr_type& x, const ptr_type& y) {
297                return
298                    x.get()->getOrCreateStateSet()->getBinNumber() >
299                    y.get()->getOrCreateStateSet()->getBinNumber()
300                ;
301            }
302        };
303
304        point_type         _width;
305        point_type         _height;
306        point_type         _windowWidth;
307        point_type         _windowHeight;
308        unsigned int       _flags;
309        unsigned int       _nodeMask;
310        osgViewer::View*   _view;
311        float              _lastX;
312        float              _lastY;
313        EventInterface*    _lastEvent;
314        EventInterface*    _lastPush;
315        PointerDirection   _lastVertical;
316        PointerDirection   _lastHorizontal;
317        PointerFocusMode   _focusMode;
318        bool               _leftDown;
319        bool               _middleDown;
320        bool               _rightDown;
321
322        osgGA::GUIEventAdapter::ScrollingMotion _scrolling;
323
324        osg::ref_ptr<ScriptEngine> _lua;
325        osg::ref_ptr<ScriptEngine> _python;
326        osg::ref_ptr<StyleManager> _styleManager;
327
328        osg::observer_ptr<Widget> _widget;
329        osg::observer_ptr<Window> _focused;
330        osg::observer_ptr<Window> _pickWindow;
331
332        void childInserted (unsigned int);
333        void childRemoved  (unsigned int, unsigned int);
334
335        bool _handleMousePushed   (float, float, bool&);
336        bool _handleMouseReleased (float, float, bool&);
337        bool _handleMouseScrolled (float, float, bool = false);
338        void _getPointerXYDiff    (float&, float&);
339        void _updatePickWindow    (const WidgetList*, point_type, point_type);
340
341};
342
343// We use a template here because the container could be a list or a vector; or something
344// else that supports iteration!
345template<typename T>
346EventInterface* WindowManager::getFirstEventInterface(T& container, Event& ev) {
347    if(!container.size()) return 0;
348
349    // See if we can find a Widget that responds to this event...
350    for(typename T::iterator i = container.begin(); i != container.end(); i++) {
351        Widget* widget = i->get();
352
353        // If so, set the _widget/_window members and return it.
354        if(widget->getEventMask() & ev.type) {
355            ev._window = widget->getParent();
356            ev._widget = widget;
357
358            return widget;
359        }
360    }
361
362    // If we can't find a Widget that will accept this event, try and recurse all
363    // of the parent Windows and find one that can.
364    WindowList windowList;
365
366    Window* parent = container.back()->getParent();
367
368    if(parent) {
369        parent->getParentList(windowList);
370
371        // A WindowList from getParentList includes the Window the method was called
372        // on, and the entire tree of parentage.
373        for(WindowList::iterator i = windowList.begin(); i != windowList.end(); i++) {
374            Window* window = i->get();
375
376            if(window->getEventMask() & ev.type) {
377                ev._window = window;
378
379                return window;
380            }
381        }
382    }
383
384    return 0;
385}
386
387}
388
389#endif
Note: See TracBrowser for help on using the browser.