root/OpenSceneGraph/trunk/src/osgPresentation/deprecated/Timeout.cpp @ 13721

Revision 13721, 12.3 kB (checked in by robert, 33 hours ago)

Added support for changing background colour of LineEdit? widget when focus changes

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 <osgPresentation/deprecated/Timeout>
15#include <osgUtil/CullVisitor>
16#include <osgGA/EventVisitor>
17
18using namespace osgPresentation;
19
20
21class OperationVisitor : public osg::NodeVisitor
22{
23public:
24
25    enum Operation
26    {
27        ENTER,
28        LEAVE,
29        RESET
30    };
31
32    OperationVisitor(Operation op) : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), _operation(op), _sleepTime(0.0) {}
33
34    void apply(osg::Node& node)
35    {
36        if (node.getStateSet()) process(node.getStateSet());
37        traverse(node);
38    }
39
40    void apply(osg::Geode& geode)
41    {
42        apply(static_cast<osg::Node&>(geode));
43
44        for(unsigned int i=0;i<geode.getNumDrawables();++i)
45        {
46            osg::Drawable* drawable = geode.getDrawable(i);
47            if (drawable->getStateSet()) process(drawable->getStateSet());
48        }
49    }
50
51    virtual void process(osg::StateSet* ss)
52    {
53        for(unsigned int i=0;i<ss->getTextureAttributeList().size();++i)
54        {
55            osg::Texture* texture = dynamic_cast<osg::Texture*>(ss->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
56            osg::Image* image = texture ? texture->getImage(0) : 0;
57            osg::ImageStream* imageStream = dynamic_cast<osg::ImageStream*>(image);
58            if (imageStream) process(imageStream);
59        }
60    }
61
62    void process(osg::ImageStream* video)
63    {
64        if (_operation==ENTER)
65        {
66            video->rewind();
67            video->play();
68
69            _sleepTime = 0.2;
70        }
71        else if (_operation==LEAVE)
72        {
73            video->pause();
74        }
75        else if (_operation==RESET)
76        {
77            video->rewind();
78
79            _sleepTime = 0.2;
80        }
81    }
82
83    double sleepTime() const { return _sleepTime; }
84
85    Operation   _operation;
86    double      _sleepTime;
87};
88
89
90HUDSettings::HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask):
91    _slideDistance(slideDistance),
92    _eyeOffset(eyeOffset),
93    _leftMask(leftMask),
94    _rightMask(rightMask)
95{
96}
97
98HUDSettings::~HUDSettings()
99{
100}
101
102bool HUDSettings::getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
103{
104    matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0));
105
106    if (nv)
107    {
108        if (nv->getTraversalMask()==_leftMask)
109        {
110            matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0));
111        }
112        else if (nv->getTraversalMask()==_rightMask)
113        {
114            matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0));
115        }
116    }
117
118    return true;
119}
120
121bool HUDSettings::getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
122{
123    osg::Matrix modelView;
124    getModelViewMatrix(modelView,nv);
125    matrix.invert(modelView);
126    return true;
127}
128
129
130
131
132Timeout::Timeout(HUDSettings* hudSettings):
133    _previousFrameNumber(-1),
134    _timeOfLastEvent(0.0),
135    _displayTimeout(false),
136    _idleDurationBeforeTimeoutDisplay(DBL_MAX),
137    _idleDurationBeforeTimeoutAction(DBL_MAX),
138    _keyStartsTimoutDisplay(0),
139    _keyDismissTimoutDisplay(0),
140    _keyRunTimeoutAction(0)
141{
142    _hudSettings = hudSettings;
143    setCullingActive(false);
144    setNumChildrenRequiringEventTraversal(1);
145}
146
147/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
148Timeout::Timeout(const Timeout& timeout,const osg::CopyOp& copyop):
149    osg::Transform(timeout, copyop),
150    _hudSettings(timeout._hudSettings)
151{
152    setDataVariance(osg::Object::DYNAMIC);
153    setReferenceFrame(osg::Transform::ABSOLUTE_RF);
154}
155
156Timeout::~Timeout()
157{
158}
159
160bool Timeout::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
161{
162    if (_hudSettings.valid()) return _hudSettings->getModelViewMatrix(matrix,nv);
163    else return false;
164}
165
166bool Timeout::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
167{
168    if (_hudSettings.valid()) return _hudSettings->getInverseModelViewMatrix(matrix,nv);
169    else return false;
170}
171
172void Timeout::broadcastEvent(osgViewer::Viewer* viewer, const osgPresentation::KeyPosition& keyPos)
173{
174    osg::ref_ptr<osgGA::GUIEventAdapter> event = new osgGA::GUIEventAdapter;
175
176    if (keyPos._key!=0) event->setEventType(osgGA::GUIEventAdapter::KEYDOWN);
177    else event->setEventType(osgGA::GUIEventAdapter::MOVE);
178
179    if (keyPos._key!=0) event->setKey(keyPos._key);
180    if (keyPos._x!=FLT_MAX) event->setX(keyPos._x);
181    if (keyPos._y!=FLT_MAX) event->setY(keyPos._y);
182
183    event->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
184
185    // dispatch cloned event to devices
186    osgViewer::View::Devices& devices = viewer->getDevices();
187    for(osgViewer::View::Devices::iterator i = devices.begin(); i != devices.end(); ++i)
188    {
189        if((*i)->getCapabilities() & osgGA::Device::SEND_EVENTS)
190        {
191            (*i)->sendEvent(*event);
192        }
193    }
194}
195void Timeout::traverse(osg::NodeVisitor& nv)
196{
197    if (nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR)
198    {
199        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
200        if (_displayTimeout && cv)
201        {
202            osgUtil::RenderStage* previous_stage = cv->getCurrentRenderBin()->getStage();
203
204            osg::ref_ptr<osgUtil::RenderStage> rs = new osgUtil::RenderStage;
205
206            osg::ColorMask* colorMask = previous_stage->getColorMask();
207            rs->setColorMask(colorMask);
208
209            // set up the viewport.
210            osg::Viewport* viewport = previous_stage->getViewport();
211            rs->setViewport( viewport );
212
213            rs->setClearMask(GL_DEPTH_BUFFER_BIT);
214
215            // record the render bin, to be restored after creation
216            // of the render to text
217            osgUtil::RenderBin* previousRenderBin = cv->getCurrentRenderBin();
218
219            // set the current renderbin to be the newly created stage.
220            cv->setCurrentRenderBin(rs.get());
221
222            // traverse the subgraph
223            {
224                Transform::traverse(nv);
225            }
226
227            // restore the previous renderbin.
228            cv->setCurrentRenderBin(previousRenderBin);
229
230            // and the render to texture stage to the current stages
231            // dependancy list.
232            cv->getCurrentRenderBin()->getStage()->addPostRenderStage(rs.get(),0);
233        }
234    }
235    else if (nv.getVisitorType()==osg::NodeVisitor::EVENT_VISITOR)
236    {
237        int deltaFrameNumber = (nv.getFrameStamp()->getFrameNumber()-_previousFrameNumber);
238        _previousFrameNumber = nv.getFrameStamp()->getFrameNumber();
239
240        bool needToRecordEventTime = false;
241        bool needToAction = false;
242
243        if (deltaFrameNumber>1)
244        {
245            needToRecordEventTime = true;
246        }
247
248        bool previous_displayTimeout = _displayTimeout;
249        bool needToDismiss = false;
250
251        osgGA::EventVisitor* ev = dynamic_cast<osgGA::EventVisitor*>(&nv);
252        osgViewer::Viewer* viewer = ev ? dynamic_cast<osgViewer::Viewer*>(ev->getActionAdapter()) : 0;
253        if (ev)
254        {
255            osgGA::EventQueue::Events& events = ev->getEvents();
256            for(osgGA::EventQueue::Events::iterator itr = events.begin();
257                itr != events.end();
258                ++itr)
259            {
260                osgGA::GUIEventAdapter* event = itr->get();
261
262                bool keyEvent = event->getEventType()==osgGA::GUIEventAdapter::KEYDOWN ||  event->getEventType()==osgGA::GUIEventAdapter::KEYUP;
263
264                if (keyEvent && event->getKey()==_keyStartsTimoutDisplay)
265                {
266                    OSG_NOTICE<<"_keyStartsTimoutDisplay pressed"<<std::endl;
267                    _displayTimeout = true;
268                }
269                else if (keyEvent && event->getKey()==_keyDismissTimoutDisplay)
270                {
271                    OSG_NOTICE<<"_keyDismissTimoutDisplay pressed"<<std::endl;
272                    needToRecordEventTime = true;
273                    needToDismiss = _displayTimeout;
274                    _displayTimeout = false;
275                }
276                else if (keyEvent && event->getKey()==_keyRunTimeoutAction)
277                {
278                    OSG_NOTICE<<"_keyRunTimeoutAction pressed"<<std::endl;
279                    _displayTimeout = false;
280                    needToRecordEventTime = true;
281                    needToAction = true;
282                }
283                else if (event->getEventType()!=osgGA::GUIEventAdapter::FRAME)
284                {
285                    needToRecordEventTime = true;
286                    needToDismiss = _displayTimeout;
287                    _displayTimeout = false;
288                }
289            }
290        }
291
292
293        if (needToRecordEventTime)
294        {
295            _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();
296        }
297
298        double timeSinceLastEvent = nv.getFrameStamp() ? nv.getFrameStamp()->getReferenceTime()-_timeOfLastEvent : 0.0;
299
300        if (timeSinceLastEvent>_idleDurationBeforeTimeoutDisplay)
301        {
302            _displayTimeout = true;
303        }
304
305        if (timeSinceLastEvent>_idleDurationBeforeTimeoutAction)
306        {
307            _displayTimeout = false;
308            needToAction = true;
309            needToDismiss = false;
310        }
311
312        if (!previous_displayTimeout && _displayTimeout)
313        {
314            if (viewer && (_displayBroadcastKeyPos._key!=0 || _displayBroadcastKeyPos._x!=FLT_MAX || _displayBroadcastKeyPos._y!=FLT_MAX))
315            {
316                OSG_NOTICE<<"Doing display broadcast key event"<<_displayBroadcastKeyPos._key<<std::endl;
317                broadcastEvent(viewer, _displayBroadcastKeyPos);
318            }
319
320            OperationVisitor leave(OperationVisitor::ENTER);
321            accept(leave);
322
323            if (leave.sleepTime()!=0.0)
324            {
325                OSG_NOTICE<<"Pausing for "<<leave.sleepTime()<<std::endl;
326                OpenThreads::Thread::microSleep(static_cast<unsigned int>(1000000.0*leave.sleepTime()));
327                OSG_NOTICE<<"Finished Pause "<<std::endl;
328            }
329
330        }
331
332
333        if (needToDismiss)
334        {
335            if (viewer && (_dismissBroadcastKeyPos._key!=0 || _dismissBroadcastKeyPos._x!=FLT_MAX || _dismissBroadcastKeyPos._y!=FLT_MAX))
336            {
337                OSG_NOTICE<<"Doing dismiss broadcast key event"<<_dismissBroadcastKeyPos._key<<std::endl;
338                broadcastEvent(viewer, _dismissBroadcastKeyPos);
339            }
340
341            OperationVisitor leave(OperationVisitor::LEAVE);
342            accept(leave);
343        }
344
345        Transform::traverse(nv);
346
347
348        if (needToAction)
349        {
350            OSG_NOTICE<<"Do timeout action"<<std::endl;
351            _previousFrameNumber = -1;
352            _timeOfLastEvent = nv.getFrameStamp()->getReferenceTime();
353
354
355            if (_actionJumpData.requiresJump())
356            {
357                OSG_NOTICE<<"Doing timeout jump"<<std::endl;
358                _actionJumpData.jump(SlideEventHandler::instance());
359            }
360
361            if (_actionKeyPos._key!=0 || _actionKeyPos._x!=FLT_MAX || _actionKeyPos._y!=FLT_MAX)
362            {
363                OSG_NOTICE<<"Doing timeout key event"<<_actionKeyPos._key<<std::endl;
364                if (SlideEventHandler::instance()) SlideEventHandler::instance()->dispatchEvent(_actionKeyPos);
365            }
366
367            if (viewer && (_actionBroadcastKeyPos._key!=0 || _actionBroadcastKeyPos._x!=FLT_MAX || _actionBroadcastKeyPos._y!=FLT_MAX))
368            {
369                OSG_NOTICE<<"Doing timeout broadcast key event"<<_actionBroadcastKeyPos._key<<std::endl;
370                broadcastEvent(viewer, _actionBroadcastKeyPos);
371            }
372
373        }
374
375    }
376    else if (nv.getVisitorType()==osg::NodeVisitor::UPDATE_VISITOR)
377    {
378        if (_displayTimeout) Transform::traverse(nv);
379    }
380    else
381    {
382        if (strcmp(nv.className(),"FindOperatorsVisitor")==0)
383        {
384            OSG_NOTICE<<"Timout::traverse() "<<nv.className()<<", ignoring traversal"<<std::endl;
385        }
386        else
387        {
388            Transform::traverse(nv);
389        }
390    }
391
392
393
394}
Note: See TracBrowser for help on using the browser.