root/OpenSceneGraph/trunk/src/osgGA/EventQueue.cpp @ 13377

Revision 13377, 18.9 kB (checked in by robert, 14 hours ago)

From Jason Beverage, "It looks like the Callback header got accidentally removed from the CMakeLists.txt in the submission yesterday for the geometry instancing example."

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 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#include <osgGA/EventQueue>
15#include <osg/Notify>
16
17using namespace osgGA;
18
19EventQueue::EventQueue(GUIEventAdapter::MouseYOrientation mouseYOrientation)
20{
21    _useFixedMouseInputRange = false;
22
23    _startTick = osg::Timer::instance()->getStartTick();
24
25    _accumulateEventState = new GUIEventAdapter();
26    _accumulateEventState->setMouseYOrientation(mouseYOrientation);
27
28    _firstTouchEmulatesMouse = true;
29}
30
31EventQueue::~EventQueue()
32{
33}
34
35void EventQueue::clear()
36{
37    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_eventQueueMutex);
38    _eventQueue.clear();
39}
40
41
42void EventQueue::setEvents(Events& events)
43{
44    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_eventQueueMutex);
45    _eventQueue = events;
46}
47
48void EventQueue::appendEvents(Events& events)
49{
50    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_eventQueueMutex);
51    _eventQueue.insert(_eventQueue.end(), events.begin(), events.end());
52}
53
54void EventQueue::addEvent(GUIEventAdapter* event)
55{
56    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_eventQueueMutex);
57    _eventQueue.push_back(event);
58}
59
60bool EventQueue::takeEvents(Events& events)
61{
62    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_eventQueueMutex);
63    if (!_eventQueue.empty())
64    {
65        events.splice(events.end(), _eventQueue);
66        return true;
67    }
68    else
69    {
70        return false;
71    }
72}
73
74bool EventQueue::takeEvents(Events& events, double cutOffTime)
75{
76    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_eventQueueMutex);
77    if (!_eventQueue.empty())
78    {
79        // find last event if queue that came in before the cuttof.
80        Events::reverse_iterator ritr = _eventQueue.rbegin();
81        for(; ritr != _eventQueue.rend() && ((*ritr)->getTime() > cutOffTime); ++ritr) {}
82
83        if (ritr==_eventQueue.rend()) return false;
84
85        for(Events::iterator itr = _eventQueue.begin();
86            itr != ritr.base();
87            ++itr)
88        {
89            events.push_back(*itr);
90        }
91
92        // make sure that the events are in ascending time order, and any out of out events
93        // have their time reset to the next valid time after them in the events list.
94        double previousTime = cutOffTime;
95        for(Events::reverse_iterator itr = events.rbegin();
96            itr != events.rend();
97            ++itr)
98        {
99            if ((*itr)->getTime() > previousTime)
100            {
101                OSG_INFO<<"Reset event time from "<<(*itr)->getTime()<<" to "<<previousTime<<std::endl;
102                (*itr)->setTime(previousTime);
103            }
104            else
105            {
106                previousTime = (*itr)->getTime();
107            }
108        }
109
110        // remove the events we are taking from the original event queue.
111        _eventQueue.erase(_eventQueue.begin(), ritr.base());
112
113        return true;
114    }
115    else
116    {
117        return false;
118    }
119}
120
121bool EventQueue::copyEvents(Events& events) const
122{
123    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_eventQueueMutex);
124    if (!_eventQueue.empty())
125    {
126        events.insert(events.end(),_eventQueue.begin(),_eventQueue.end());
127        return true;
128    }
129    else
130    {
131        return false;
132    }
133}
134
135void EventQueue::syncWindowRectangleWithGraphcisContext()
136{
137    const osg::GraphicsContext::Traits* traits = (getGraphicsContext()!=0) ? getGraphicsContext()->getTraits() : 0;
138    if (traits) _accumulateEventState->setWindowRectangle(traits->x, traits->y, traits->width, traits->height, !_useFixedMouseInputRange);
139}
140
141void EventQueue::windowResize(int x, int y, int width, int height, double time)
142{
143    _accumulateEventState->setWindowRectangle(x, y, width, height, !_useFixedMouseInputRange);
144
145    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
146    event->setEventType(GUIEventAdapter::RESIZE);
147    event->setTime(time);
148
149    addEvent(event);
150}
151
152void EventQueue::penPressure(float pressure, double time)
153{
154    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
155    event->setEventType(GUIEventAdapter::PEN_PRESSURE);
156    event->setPenPressure(pressure);
157    event->setTime(time);
158
159    addEvent(event);
160}
161
162void EventQueue::penOrientation(float tiltX, float tiltY, float rotation, double time)
163{
164    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
165    event->setEventType(GUIEventAdapter::PEN_ORIENTATION);
166    event->setPenTiltX(tiltX);
167    event->setPenTiltY(tiltY);
168    event->setPenRotation(rotation);
169    event->setTime(time);
170
171    addEvent(event);
172}
173
174void EventQueue::penProximity(GUIEventAdapter::TabletPointerType pt, bool isEntering, double time)
175{
176    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
177    event->setEventType( (isEntering) ? GUIEventAdapter::PEN_PROXIMITY_ENTER : GUIEventAdapter::PEN_PROXIMITY_LEAVE);
178    event->setTabletPointerType(pt);
179    event->setTime(time);
180
181    addEvent(event);
182}
183
184void EventQueue::mouseScroll(GUIEventAdapter::ScrollingMotion sm, double time)
185{
186    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
187    event->setEventType(GUIEventAdapter::SCROLL);
188    event->setScrollingMotion(sm);
189    event->setTime(time);
190
191    addEvent(event);
192}
193
194void EventQueue::mouseScroll2D(float x, float y, double time)
195{
196    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
197    event->setEventType(GUIEventAdapter::SCROLL);
198    event->setScrollingMotionDelta(x,y);
199    event->setTime(time);
200
201    addEvent(event);
202}
203
204
205void EventQueue::mouseWarped(float x, float y)
206{
207    _accumulateEventState->setX(x);
208    _accumulateEventState->setY(y);
209}
210
211
212void EventQueue::mouseMotion(float x, float y, double time)
213{
214    _accumulateEventState->setX(x);
215    _accumulateEventState->setY(y);
216
217    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
218    event->setEventType(event->getButtonMask() ? GUIEventAdapter::DRAG : GUIEventAdapter::MOVE);
219    event->setTime(time);
220
221    addEvent(event);
222}
223
224void EventQueue::mouseButtonPress(float x, float y, unsigned int button, double time)
225{
226    _accumulateEventState->setX(x);
227    _accumulateEventState->setY(y);
228
229    switch(button)
230    {
231        case(1):
232            _accumulateEventState->setButtonMask(GUIEventAdapter::LEFT_MOUSE_BUTTON | _accumulateEventState->getButtonMask());
233            break;
234        case(2):
235            _accumulateEventState->setButtonMask(GUIEventAdapter::MIDDLE_MOUSE_BUTTON | _accumulateEventState->getButtonMask());
236            break;
237        case(3):
238            _accumulateEventState->setButtonMask(GUIEventAdapter::RIGHT_MOUSE_BUTTON | _accumulateEventState->getButtonMask());
239            break;
240    }
241
242    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
243    event->setEventType(GUIEventAdapter::PUSH);
244    event->setTime(time);
245
246    switch(button)
247    {
248        case(1):
249            event->setButton(GUIEventAdapter::LEFT_MOUSE_BUTTON);
250            break;
251        case(2):
252            event->setButton(GUIEventAdapter::MIDDLE_MOUSE_BUTTON);
253            break;
254        case(3):
255            event->setButton(GUIEventAdapter::RIGHT_MOUSE_BUTTON);
256            break;
257    }
258
259    addEvent(event);
260}
261
262void EventQueue::mouseDoubleButtonPress(float x, float y, unsigned int button, double time)
263{
264    _accumulateEventState->setX(x);
265    _accumulateEventState->setY(y);
266
267    switch(button)
268    {
269        case(1):
270            _accumulateEventState->setButtonMask(GUIEventAdapter::LEFT_MOUSE_BUTTON | _accumulateEventState->getButtonMask());
271            break;
272        case(2):
273            _accumulateEventState->setButtonMask(GUIEventAdapter::MIDDLE_MOUSE_BUTTON | _accumulateEventState->getButtonMask());
274            break;
275        case(3):
276            _accumulateEventState->setButtonMask(GUIEventAdapter::RIGHT_MOUSE_BUTTON | _accumulateEventState->getButtonMask());
277            break;
278    }
279
280    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
281    event->setEventType(GUIEventAdapter::DOUBLECLICK);
282    event->setTime(time);
283
284    switch(button)
285    {
286        case(1):
287            event->setButton(GUIEventAdapter::LEFT_MOUSE_BUTTON);
288            break;
289        case(2):
290            event->setButton(GUIEventAdapter::MIDDLE_MOUSE_BUTTON);
291            break;
292        case(3):
293            event->setButton(GUIEventAdapter::RIGHT_MOUSE_BUTTON);
294            break;
295    }
296
297    addEvent(event);
298}
299
300void EventQueue::mouseButtonRelease(float x, float y, unsigned int button, double time)
301{
302    _accumulateEventState->setX(x);
303    _accumulateEventState->setY(y);
304
305    switch(button)
306    {
307        case(1):
308            _accumulateEventState->setButtonMask(~GUIEventAdapter::LEFT_MOUSE_BUTTON & _accumulateEventState->getButtonMask());
309            break;
310        case(2):
311            _accumulateEventState->setButtonMask(~GUIEventAdapter::MIDDLE_MOUSE_BUTTON & _accumulateEventState->getButtonMask());
312            break;
313        case(3):
314            _accumulateEventState->setButtonMask(~GUIEventAdapter::RIGHT_MOUSE_BUTTON & _accumulateEventState->getButtonMask());
315            break;
316    }
317
318    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
319    event->setEventType(GUIEventAdapter::RELEASE);
320    event->setTime(time);
321
322    switch(button)
323    {
324        case(1):
325            event->setButton(GUIEventAdapter::LEFT_MOUSE_BUTTON);
326            break;
327        case(2):
328            event->setButton(GUIEventAdapter::MIDDLE_MOUSE_BUTTON);
329            break;
330        case(3):
331            event->setButton(GUIEventAdapter::RIGHT_MOUSE_BUTTON);
332            break;
333    }
334
335    addEvent(event);
336}
337
338void EventQueue::keyPress(int key, double time, int unmodifiedKey)
339{
340    switch(key)
341    {
342        case(GUIEventAdapter::KEY_Shift_L):      _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_LEFT_SHIFT | _accumulateEventState->getModKeyMask()); break;
343        case(GUIEventAdapter::KEY_Shift_R):      _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_RIGHT_SHIFT | _accumulateEventState->getModKeyMask()); break;
344        case(GUIEventAdapter::KEY_Control_L):    _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_LEFT_CTRL | _accumulateEventState->getModKeyMask()); break;
345        case(GUIEventAdapter::KEY_Control_R):    _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_RIGHT_CTRL | _accumulateEventState->getModKeyMask()); break;
346        case(GUIEventAdapter::KEY_Meta_L):       _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_LEFT_META | _accumulateEventState->getModKeyMask()); break;
347        case(GUIEventAdapter::KEY_Meta_R):       _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_RIGHT_META | _accumulateEventState->getModKeyMask()); break;
348        case(GUIEventAdapter::KEY_Alt_L):        _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_LEFT_ALT | _accumulateEventState->getModKeyMask()); break;
349        case(GUIEventAdapter::KEY_Alt_R):        _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_RIGHT_ALT | _accumulateEventState->getModKeyMask()); break;
350        case(GUIEventAdapter::KEY_Super_L):      _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_LEFT_SUPER | _accumulateEventState->getModKeyMask()); break;
351        case(GUIEventAdapter::KEY_Super_R):      _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_RIGHT_SUPER | _accumulateEventState->getModKeyMask()); break;
352        case(GUIEventAdapter::KEY_Hyper_L):      _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_LEFT_HYPER | _accumulateEventState->getModKeyMask()); break;
353        case(GUIEventAdapter::KEY_Hyper_R):      _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_RIGHT_HYPER | _accumulateEventState->getModKeyMask()); break;
354        case(GUIEventAdapter::KEY_Caps_Lock):
355        {
356            if ((_accumulateEventState->getModKeyMask() & GUIEventAdapter::MODKEY_CAPS_LOCK)!=0)
357                _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_CAPS_LOCK & _accumulateEventState->getModKeyMask());
358            else
359                _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_CAPS_LOCK | _accumulateEventState->getModKeyMask());
360            break;
361        }
362        case(GUIEventAdapter::KEY_Num_Lock):
363        {
364            if ((_accumulateEventState->getModKeyMask() & GUIEventAdapter::MODKEY_NUM_LOCK)!=0)
365                 _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_NUM_LOCK & _accumulateEventState->getModKeyMask());
366            else
367                 _accumulateEventState->setModKeyMask(GUIEventAdapter::MODKEY_NUM_LOCK | _accumulateEventState->getModKeyMask());
368            break;
369        }
370        default: break;
371    }
372
373    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
374    event->setEventType(GUIEventAdapter::KEYDOWN);
375    event->setKey(key);
376    event->setUnmodifiedKey(unmodifiedKey);
377    event->setTime(time);
378
379    addEvent(event);
380}
381
382void EventQueue::keyRelease(int key, double time, int unmodifiedKey)
383{
384    switch(key)
385    {
386        case(GUIEventAdapter::KEY_Shift_L):      _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_LEFT_SHIFT & _accumulateEventState->getModKeyMask()); break;
387        case(GUIEventAdapter::KEY_Shift_R):      _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_RIGHT_SHIFT & _accumulateEventState->getModKeyMask()); break;
388        case(GUIEventAdapter::KEY_Control_L):    _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_LEFT_CTRL & _accumulateEventState->getModKeyMask()); break;
389        case(GUIEventAdapter::KEY_Control_R):    _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_RIGHT_CTRL & _accumulateEventState->getModKeyMask()); break;
390        case(GUIEventAdapter::KEY_Meta_L):       _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_LEFT_META & _accumulateEventState->getModKeyMask()); break;
391        case(GUIEventAdapter::KEY_Meta_R):       _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_RIGHT_META & _accumulateEventState->getModKeyMask()); break;
392        case(GUIEventAdapter::KEY_Alt_L):        _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_LEFT_ALT & _accumulateEventState->getModKeyMask()); break;
393        case(GUIEventAdapter::KEY_Alt_R):        _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_RIGHT_ALT & _accumulateEventState->getModKeyMask()); break;
394        case(GUIEventAdapter::KEY_Super_L):      _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_LEFT_SUPER & _accumulateEventState->getModKeyMask()); break;
395        case(GUIEventAdapter::KEY_Super_R):      _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_RIGHT_SUPER & _accumulateEventState->getModKeyMask()); break;
396        case(GUIEventAdapter::KEY_Hyper_L):      _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_LEFT_HYPER & _accumulateEventState->getModKeyMask()); break;
397        case(GUIEventAdapter::KEY_Hyper_R):      _accumulateEventState->setModKeyMask(~GUIEventAdapter::MODKEY_RIGHT_HYPER & _accumulateEventState->getModKeyMask()); break;
398        default: break;
399    }
400
401    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
402    event->setEventType(GUIEventAdapter::KEYUP);
403    event->setKey(key);
404    event->setUnmodifiedKey(unmodifiedKey);
405    event->setTime(time);
406
407    addEvent(event);
408}
409
410
411GUIEventAdapter*  EventQueue::touchBegan(unsigned int id, GUIEventAdapter::TouchPhase phase, float x, float y, double time)
412{
413    if(_firstTouchEmulatesMouse)
414    {
415        // emulate left mouse button press
416
417        _accumulateEventState->setButtonMask(GUIEventAdapter::LEFT_MOUSE_BUTTON | _accumulateEventState->getButtonMask());
418        _accumulateEventState->setX(x);
419        _accumulateEventState->setY(y);
420    }
421
422    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
423    event->setEventType(GUIEventAdapter::PUSH);
424    event->setTime(time);
425    event->addTouchPoint(id, phase, x, y, 0);
426    if(_firstTouchEmulatesMouse)
427        event->setButton(GUIEventAdapter::LEFT_MOUSE_BUTTON);
428   
429    addEvent(event);
430
431    return event;
432}
433
434
435GUIEventAdapter*  EventQueue::touchMoved(unsigned int id, GUIEventAdapter::TouchPhase phase, float x, float y, double time)
436{
437    if(_firstTouchEmulatesMouse)
438    {
439        _accumulateEventState->setX(x);
440        _accumulateEventState->setY(y);
441    }
442
443    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
444    event->setEventType(GUIEventAdapter::DRAG);
445    event->setTime(time);
446    event->addTouchPoint(id, phase, x, y, 0);
447    addEvent(event);
448
449    return event;
450}
451
452GUIEventAdapter*  EventQueue::touchEnded(unsigned int id, GUIEventAdapter::TouchPhase phase, float x, float y, unsigned int tap_count, double time)
453{
454    if (_firstTouchEmulatesMouse)
455    {
456        _accumulateEventState->setButtonMask(~GUIEventAdapter::LEFT_MOUSE_BUTTON & _accumulateEventState->getButtonMask());
457        _accumulateEventState->setX(x);
458        _accumulateEventState->setY(y);
459    }
460
461    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
462    event->setEventType(GUIEventAdapter::RELEASE);
463    event->setTime(time);
464    event->addTouchPoint(id, phase, x, y, tap_count);
465    if(_firstTouchEmulatesMouse)
466        event->setButton(GUIEventAdapter::LEFT_MOUSE_BUTTON);
467   
468    addEvent(event);
469
470    return event;
471}
472
473
474void EventQueue::closeWindow(double time)
475{
476    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
477    event->setEventType(GUIEventAdapter::CLOSE_WINDOW);
478    event->setTime(time);
479
480    addEvent(event);
481}
482
483void EventQueue::quitApplication(double time)
484{
485    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
486    event->setEventType(GUIEventAdapter::QUIT_APPLICATION);
487    event->setTime(time);
488
489    addEvent(event);
490}
491
492
493void EventQueue::frame(double time)
494{
495    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
496    event->setEventType(GUIEventAdapter::FRAME);
497    event->setTime(time);
498   
499    // OSG_NOTICE<<"frame("<<time<<"), event->getX()="<<event->getX()<<", event->getY()="<<event->getY()<<", event->getXmin()="<<event->getXmin()<<", event->getYmin()="<<event->getYmin()<<", event->getXmax()="<<event->getXmax()<<", event->getYmax()="<<event->getYmax()<<std::endl;
500
501    addEvent(event);
502}
503
504GUIEventAdapter* EventQueue::createEvent()
505{
506    if (_accumulateEventState.valid()) return new GUIEventAdapter(*_accumulateEventState.get());
507    else return new GUIEventAdapter();
508}
509
510void EventQueue::userEvent(osg::Referenced* userEventData, double time)
511{
512    GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState);
513    event->setEventType(GUIEventAdapter::USER);
514    event->setUserData(userEventData);
515    event->setTime(time);
516
517    addEvent(event);
518}
519
Note: See TracBrowser for help on using the browser.