1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
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.
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.
14#ifndef OSGGA_GUIEVENTADAPTER
15#define OSGGA_GUIEVENTADAPTER 1
19#include <osg/GraphicsContext>
25struct PointerData : public osg::Referenced
36 PointerData(osg::Object* obj, float in_x, float in_xMin, float in_xMax, float in_y, float in_yMin, float in_yMax):
45 PointerData(const PointerData& pd):
55 PointerData& operator = (const PointerData& pd)
57 if (&pd==this) return *this;
70 osg::observer_ptr<osg::Object> object;
74 float getXnormalized() const { return (x-xMin)/(xMax-xMin)*2.0f-1.0f; }
75 float getYnormalized() const { return (y-yMin)/(yMax-yMin)*2.0f-1.0f; }
79/** Event class for storing Keyboard, mouse and window events.
81class OSGGA_EXPORT GUIEventAdapter : public Event
85 enum MouseButtonMask {
86 LEFT_MOUSE_BUTTON = 1<<0,
87 MIDDLE_MOUSE_BUTTON = 1<<1,
88 RIGHT_MOUSE_BUTTON = 1<<2
103 PEN_PRESSURE = 1<<10,
104 PEN_ORIENTATION = 1<<11,
105 PEN_PROXIMITY_ENTER = 1<<12,
106 PEN_PROXIMITY_LEAVE = 1<<13,
107 CLOSE_WINDOW = 1<<14,
108 QUIT_APPLICATION = 1<<15,
157 KEY_Ampersand = 0x26,
159 KEY_Leftparen = 0x28,
160 KEY_Rightparen = 0x29,
168 KEY_Semicolon = 0x3B,
174 KEY_Leftbracket = 0x5B,
175 KEY_Backslash = 0x5C,
176 KEY_Rightbracket = 0x5D,
178 KEY_Underscore = 0x5F,
179 KEY_Backquote = 0x60,
181 KEY_BackSpace = 0xFF08, /* back space, back char */
183 KEY_Linefeed = 0xFF0A, /* Linefeed, LF */
185 KEY_Return = 0xFF0D, /* Return, enter */
186 KEY_Pause = 0xFF13, /* Pause, hold */
187 KEY_Scroll_Lock = 0xFF14,
188 KEY_Sys_Req = 0xFF15,
190 KEY_Delete = 0xFFFF, /* Delete, rubout */
193 /* Cursor control & motion */
196 KEY_Left = 0xFF51, /* Move left, left arrow */
197 KEY_Up = 0xFF52, /* Move up, up arrow */
198 KEY_Right = 0xFF53, /* Move right, right arrow */
199 KEY_Down = 0xFF54, /* Move down, down arrow */
200 KEY_Prior = 0xFF55, /* Prior, previous */
201 KEY_Page_Up = 0xFF55,
202 KEY_Next = 0xFF56, /* Next */
203 KEY_Page_Down = 0xFF56,
204 KEY_End = 0xFF57, /* EOL */
205 KEY_Begin = 0xFF58, /* BOL */
210 KEY_Select = 0xFF60, /* Select, mark */
212 KEY_Execute = 0xFF62, /* Execute, run, do */
213 KEY_Insert = 0xFF63, /* Insert, insert here */
214 KEY_Undo = 0xFF65, /* Undo, oops */
215 KEY_Redo = 0xFF66, /* redo, again */
216 KEY_Menu = 0xFF67, /* On Windows, this is VK_APPS, the context-menu key */
217 KEY_Find = 0xFF68, /* Find, search */
218 KEY_Cancel = 0xFF69, /* Cancel, stop, abort, exit */
219 KEY_Help = 0xFF6A, /* Help */
221 KEY_Mode_switch = 0xFF7E, /* Character set switch */
222 KEY_Script_switch = 0xFF7E, /* Alias for mode_switch */
223 KEY_Num_Lock = 0xFF7F,
225 /* Keypad Functions, keypad numbers cleverly chosen to map to ascii */
227 KEY_KP_Space = 0xFF80, /* space */
229 KEY_KP_Enter = 0xFF8D, /* enter */
230 KEY_KP_F1 = 0xFF91, /* PF1, KP_A, ... */
234 KEY_KP_Home = 0xFF95,
235 KEY_KP_Left = 0xFF96,
237 KEY_KP_Right = 0xFF98,
238 KEY_KP_Down = 0xFF99,
239 KEY_KP_Prior = 0xFF9A,
240 KEY_KP_Page_Up = 0xFF9A,
241 KEY_KP_Next = 0xFF9B,
242 KEY_KP_Page_Down = 0xFF9B,
244 KEY_KP_Begin = 0xFF9D,
245 KEY_KP_Insert = 0xFF9E,
246 KEY_KP_Delete = 0xFF9F,
247 KEY_KP_Equal = 0xFFBD, /* equals */
248 KEY_KP_Multiply = 0xFFAA,
250 KEY_KP_Separator = 0xFFAC, /* separator, often comma */
251 KEY_KP_Subtract = 0xFFAD,
252 KEY_KP_Decimal = 0xFFAE,
253 KEY_KP_Divide = 0xFFAF,
267 * Auxiliary Functions; note the duplicate definitions for left and right
268 * function keys; Sun keyboards and a few other manufactures have such
269 * function key groups on the left and/or right sides of the keyboard.
270 * We've not found a keyboard with more than 35 function keys total.
311 KEY_Shift_L = 0xFFE1, /* Left shift */
312 KEY_Shift_R = 0xFFE2, /* Right shift */
313 KEY_Control_L = 0xFFE3, /* Left control */
314 KEY_Control_R = 0xFFE4, /* Right control */
315 KEY_Caps_Lock = 0xFFE5, /* Caps lock */
316 KEY_Shift_Lock = 0xFFE6, /* Shift lock */
318 KEY_Meta_L = 0xFFE7, /* Left meta */
319 KEY_Meta_R = 0xFFE8, /* Right meta */
320 KEY_Alt_L = 0xFFE9, /* Left alt */
321 KEY_Alt_R = 0xFFEA, /* Right alt */
322 KEY_Super_L = 0xFFEB, /* Left super */
323 KEY_Super_R = 0xFFEC, /* Right super */
324 KEY_Hyper_L = 0xFFED, /* Left hyper */
325 KEY_Hyper_R = 0xFFEE /* Right hyper */
331 MODKEY_LEFT_SHIFT = 0x0001,
332 MODKEY_RIGHT_SHIFT = 0x0002,
333 MODKEY_LEFT_CTRL = 0x0004,
334 MODKEY_RIGHT_CTRL = 0x0008,
335 MODKEY_LEFT_ALT = 0x0010,
336 MODKEY_RIGHT_ALT = 0x0020,
337 MODKEY_LEFT_META = 0x0040,
338 MODKEY_RIGHT_META = 0x0080,
339 MODKEY_LEFT_SUPER = 0x0100,
340 MODKEY_RIGHT_SUPER = 0x0200,
341 MODKEY_LEFT_HYPER = 0x0400,
342 MODKEY_RIGHT_HYPER = 0x0800,
343 MODKEY_NUM_LOCK = 0x1000,
344 MODKEY_CAPS_LOCK = 0x2000,
345 MODKEY_CTRL = (MODKEY_LEFT_CTRL|MODKEY_RIGHT_CTRL),
346 MODKEY_SHIFT = (MODKEY_LEFT_SHIFT|MODKEY_RIGHT_SHIFT),
347 MODKEY_ALT = (MODKEY_LEFT_ALT|MODKEY_RIGHT_ALT),
348 MODKEY_META = (MODKEY_LEFT_META|MODKEY_RIGHT_META),
349 MODKEY_SUPER = (MODKEY_LEFT_SUPER|MODKEY_RIGHT_SUPER),
350 MODKEY_HYPER = (MODKEY_LEFT_HYPER|MODKEY_RIGHT_HYPER)
353 enum MouseYOrientation
355 Y_INCREASING_UPWARDS,
356 Y_INCREASING_DOWNWARDS
369 enum TabletPointerType
386 class TouchData : public osg::Object {
394 unsigned int tapCount;
395 TouchPoint() : id(0), phase(TOUCH_UNKNOWN), x(0.0f), y(0.0f), tapCount(0) {}
396 TouchPoint(unsigned int in_id, TouchPhase in_phase, float in_x, float in_y, unsigned int in_tap_count)
401 tapCount(in_tap_count)
406 typedef std::vector<TouchPoint> TouchSet;
408 typedef TouchSet::iterator iterator;
409 typedef TouchSet::const_iterator const_iterator;
411 TouchData() : osg::Object() {}
413 TouchData(const TouchData& td, const osg::CopyOp& copyop):
414 osg::Object(td,copyop),
415 _touches(td._touches) {}
418 META_Object(osgGA, TouchData);
421 unsigned int getNumTouchPoints() const { return static_cast<unsigned int>(_touches.size()); }
423 iterator begin() { return _touches.begin(); }
424 const_iterator begin() const { return _touches.begin(); }
426 iterator end() { return _touches.end(); }
427 const_iterator end() const { return _touches.end(); }
429 const TouchPoint get(unsigned int i) const { return _touches[i]; }
433 virtual ~TouchData() {}
435 void addTouchPoint(unsigned int id, TouchPhase phase, float x, float y, unsigned int tap_count) {
436 _touches.push_back(TouchPoint(id, phase, x, y, tap_count));
441 friend class GUIEventAdapter;
448 GUIEventAdapter(const GUIEventAdapter& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
450 META_Object(osgGA, GUIEventAdapter);
452 virtual GUIEventAdapter* asGUIEventAdapter() { return this; }
453 virtual const GUIEventAdapter* asGUIEventAdapter() const { return this; }
456 /** Get the accumulated event state singleton.
457 * Typically all EventQueue will share this single GUIEventAdapter object for tracking
458 * the mouse position, keyboard and mouse masks. */
459 static osg::ref_ptr<GUIEventAdapter>& getAccumulatedEventState();
462 /** set the event type. */
463 void setEventType(EventType Type) { _eventType = Type; }
465 /** get the event type. */
466 virtual EventType getEventType() const { return _eventType; }
468 /** deprecated function for getting time of event. */
469 double time() const { return _time; }
472 void setGraphicsContext(osg::GraphicsContext* context) { _context = context; }
473 osg::GraphicsContext* getGraphicsContext() { return _context.get(); }
474 const osg::GraphicsContext* getGraphicsContext() const { return _context.get(); }
477 /** set window rectangle. */
478 void setWindowRectangle(int x, int y, int width, int height, bool updateMouseRange = true);
480 /** set window x origin.*/
481 void setWindowX(int v) { _windowX = v; }
483 /** get window x origin.*/
484 int getWindowX() const { return _windowX; }
486 /** set window x origin.*/
487 void setWindowY(int v) { _windowY = v; }
489 /** get window y origin.*/
490 int getWindowY() const { return _windowY; }
492 /** set window width.*/
493 void setWindowWidth(int v) { _windowWidth = v; }
495 /** get window width.*/
496 int getWindowWidth() const { return _windowWidth; }
498 /** set window height.*/
499 void setWindowHeight(int v) { _windowHeight = v; }
501 /** get window height.*/
502 int getWindowHeight() const { return _windowHeight; }
505 /** set key pressed. */
506 inline void setKey(int key) { _key = key; }
508 /** get key pressed, return -1 if inappropriate for this GUIEventAdapter. */
509 virtual int getKey() const { return _key; }
511 /** set virtual key pressed. */
512 void setUnmodifiedKey(int key) { _unmodifiedKey = key; }
514 /** get virtual key pressed. */
515 int getUnmodifiedKey() const { return _unmodifiedKey; }
517 /** set button pressed/released.*/
518 void setButton(int button) { _button = button; }
520 /** button pressed/released, return -1 if inappropriate for this GUIEventAdapter.*/
521 int getButton() const { return _button; }
524 /** set mouse input range. */
525 void setInputRange(float Xmin, float Ymin, float Xmax, float Ymax);
527 /** set mouse minimum x. */
528 void setXmin(float v) { _Xmin = v; }
530 /** get mouse minimum x. */
531 float getXmin() const { return _Xmin; }
533 /** set mouse maximum x. */
534 void setXmax(float v) { _Xmax = v; }
536 /** get mouse maximum x. */
537 float getXmax() const { return _Xmax; }
539 /** set mouse minimum x. */
540 void setYmin(float v) { _Ymin = v; }
542 /** get mouse minimum y. */
543 float getYmin() const { return _Ymin; }
545 /** set mouse maximum y. */
546 void setYmax(float v) { _Ymax = v; }
548 /** get mouse maximum y. */
549 float getYmax() const { return _Ymax; }
551 /** set current mouse x position.*/
552 void setX(float x) { _mx = x; }
554 /** get current mouse x position.*/
555 float getX() const { return _mx; }
557 /** set current mouse y position.*/
558 void setY(float y) { _my = y; }
560 /** get current mouse y position.*/
561 float getY() const { return _my; }
564 inline float getXnormalized() const
566 return _pointerDataList.size()>=1 ?
567 _pointerDataList[_pointerDataList.size()-1]->getXnormalized():
568 2.0f*(getX()-getXmin())/(getXmax()-getXmin())-1.0f;
571 inline float getYnormalized() const
573 if (_pointerDataList.size()>=1) return _pointerDataList[_pointerDataList.size()-1]->getYnormalized();
574 if (_mouseYOrientation==Y_INCREASING_UPWARDS) return 2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f;
575 else return -(2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f);
579 * return the current mouse x value normalized to the range of -1 to 1.
580 * -1 would be the left hand side of the window.
581 * 0.0 would be the middle of the window.
582 * +1 would be the right hand side of the window.
584 inline float getXnormalized() const { return 2.0f*(getX()-getXmin())/(getXmax()-getXmin())-1.0f; }
587 * return the current mouse y value normalized to the range of -1 to 1.
588 * -1 would be the bottom of the window.
589 * 0.0 would be the middle of the window.
590 * +1 would be the top of the window.
592 inline float getYnormalized() const
594 if (_mouseYOrientation==Y_INCREASING_UPWARDS) return 2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f;
595 else return -(2.0f*(getY()-getYmin())/(getYmax()-getYmin())-1.0f);
599 /// set mouse-Y orientation (mouse-Y increases upwards or downwards).
600 void setMouseYOrientation(MouseYOrientation myo) { _mouseYOrientation = myo; }
602 /// get mouse-Y orientation (mouse-Y increases upwards or downwards).
603 MouseYOrientation getMouseYOrientation() const { return _mouseYOrientation; }
605 /// set mouse-Y orientation (mouse-Y increases upwards or downwards) and recompute variables
606 void setMouseYOrientationAndUpdateCoords(MouseYOrientation myo);
608 /// set current mouse button state.
609 void setButtonMask(int mask) { _buttonMask = mask; }
611 /// get current mouse button state.
612 int getButtonMask() const { return _buttonMask; }
614 /// set modifier key mask.
615 void setModKeyMask(int mask) { _modKeyMask = mask; }
617 /// get modifier key mask.
618 int getModKeyMask() const { return _modKeyMask; }
620 /// set scrolling motion (for EventType::SCROLL).
621 void setScrollingMotion(ScrollingMotion motion) { _scrolling.motion = motion; }
623 /// get scrolling motion (for EventType::SCROLL).
624 ScrollingMotion getScrollingMotion() const { return _scrolling.motion; }
626 /// set the scrolling delta to x,y and the scrolling motion to SCROLL_2D.
627 void setScrollingMotionDelta(float x, float y) {
628 _scrolling.motion = SCROLL_2D;
629 _scrolling.deltaX = x;
630 _scrolling.deltaY = y;
633 /// set the scrolling x-delta.
634 void setScrollingDeltaX(float v) { _scrolling.deltaX = v; }
636 /// get the scrolling x-delta.
637 float getScrollingDeltaX() const { return _scrolling.deltaX; }
639 /// set the scrolling y-delta.
640 void setScrollingDeltaY(float v) { _scrolling.deltaY = v; }
642 /// get the scrolling y-delta.
643 float getScrollingDeltaY() const { return _scrolling.deltaY; }
646 /// set the tablet pen pressure (range 0..1).
647 void setPenPressure(float pressure) { _tabletPen.pressure = pressure; }
649 /// get the tablet pen pressure (range 0..1).
650 float getPenPressure() const { return _tabletPen.pressure; }
652 /// set the tablet pen tiltX in degrees.
653 void setPenTiltX(float tiltX) { _tabletPen.tiltX = tiltX; }
655 /// get the tablet pen tiltX in degrees.
656 float getPenTiltX() const { return _tabletPen.tiltX; }
658 /// set the tablet pen tiltY in degrees.
659 void setPenTiltY(float tiltY) { _tabletPen.tiltY = tiltY; }
661 /// get the tablet pen tiltY in degrees.
662 float getPenTiltY() const { return _tabletPen.tiltY; }
664 /// set the tablet pen rotation around the Z-axis in degrees.
665 void setPenRotation(float rotation) { _tabletPen.rotation = rotation; }
667 /// get the tablet pen rotation around the Z-axis in degrees.
668 float getPenRotation() const { return _tabletPen.rotation; }
670 /// set the tablet pointer type.
671 void setTabletPointerType(TabletPointerType pt) { _tabletPen.tabletPointerType = pt; }
673 /// get the tablet pointer type.
674 TabletPointerType getTabletPointerType() const { return _tabletPen.tabletPointerType; }
676 /// set the orientation from a tablet input device as a matrix.
677 const osg::Matrix getPenOrientation() const;
679 void addTouchPoint(unsigned int id, TouchPhase phase, float x, float y, unsigned int tapCount = 0);
681 void setTouchData(TouchData* td) { _touchData = td; }
682 TouchData* getTouchData() const { return _touchData.get(); }
683 bool isMultiTouchEvent() const { return (_touchData.valid()); }
685 inline float getTouchPointNormalizedX(unsigned int ndx) const {
686 return (getTouchData()->get(ndx).x-_Xmin)/(_Xmax-_Xmin)*2.0f-1.0f;
689 inline float getTouchPointNormalizedY(unsigned int ndx) const {
690 if (_mouseYOrientation==Y_INCREASING_UPWARDS)
691 return (getTouchData()->get(ndx).y-_Ymin)/(_Ymax-_Ymin)*2.0f-1.0f;
693 return -((getTouchData()->get(ndx).y-_Ymin)/(_Ymax-_Ymin)*2.0f-1.0f);
696 typedef std::vector< osg::ref_ptr<PointerData> > PointerDataList;
697 void setPointerDataList(const PointerDataList& pdl) { _pointerDataList = pdl; }
698 PointerDataList& getPointerDataList() { return _pointerDataList; }
699 const PointerDataList& getPointerDataList() const { return _pointerDataList; }
701 unsigned int getNumPointerData() const { return static_cast<unsigned int>(_pointerDataList.size()); }
702 PointerData* getPointerData(unsigned int i) { return _pointerDataList[i].get(); }
703 const PointerData* getPointerData(unsigned int i) const { return _pointerDataList[i].get(); }
705 PointerData* getPointerData(osg::Object* obj) { for(unsigned int i=0;i<_pointerDataList.size(); ++i) { if (_pointerDataList[i]->object==obj) return _pointerDataList[i].get(); } return 0; }
706 const PointerData* getPointerData(osg::Object* obj) const { for(unsigned int i=0;i<_pointerDataList.size(); ++i) { if (_pointerDataList[i]->object==obj) return _pointerDataList[i].get(); } return 0; }
707 void addPointerData(PointerData* pd) { _pointerDataList.push_back(pd); }
709 void copyPointerDataFrom(const osgGA::GUIEventAdapter& sourceEvent);
713 /** Force users to create on heap, so that multiple referencing is safe.*/
714 virtual ~GUIEventAdapter();
716 EventType _eventType;
718 osg::observer_ptr<osg::GraphicsContext> _context;
732 MouseYOrientation _mouseYOrientation;
735 ScrollingMotion motion;
739 Scrolling() : motion(SCROLL_NONE), deltaX(0), deltaY(0) {}
740 Scrolling(const Scrolling& rhs) : motion(rhs.motion), deltaX(rhs.deltaX), deltaY(rhs.deltaY) {}
742 Scrolling _scrolling;
749 TabletPointerType tabletPointerType;
751 TabletPen() : pressure(0), tiltX(0), tiltY(0), rotation(0), tabletPointerType(UNKNOWN) {}
752 TabletPen(const TabletPen& rhs) : pressure(rhs.pressure), tiltX(rhs.tiltX), tiltY(rhs.tiltY), rotation(rhs.rotation), tabletPointerType(rhs.tabletPointerType) {}
754 TabletPen _tabletPen;
756 osg::ref_ptr<TouchData> _touchData;
759 PointerDataList _pointerDataList;