1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2018 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 SLIDEEVENTHANDLER
15#define SLIDEEVENTHANDLER 1
19#include <osg/ValueObject>
20#include <osg/ImageSequence>
22#include <osgGA/GUIEventHandler>
23#include <osgViewer/Viewer>
25#include <osgPresentation/CompileSlideCallback>
26#include <osgPresentation/PropertyManager>
28namespace osgPresentation
32class SlideEventHandler;
34/// Operations related to click to run/load/key events.
45struct JumpData : public osg::Object
52 JumpData(bool in_relativeJump, int in_slideNum, int in_layerNum):
53 relativeJump(in_relativeJump),
54 slideNum(in_slideNum),
55 layerNum(in_layerNum) {}
57 JumpData(const std::string& in_slideName, const std::string& in_layerName):
61 slideName(in_slideName),
62 layerName(in_layerName) {}
64 JumpData(const JumpData& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
65 osg::Object(rhs, copyop),
66 relativeJump(rhs.relativeJump),
67 slideNum(rhs.slideNum),
68 layerNum(rhs.layerNum),
69 slideName(rhs.slideName),
70 layerName(rhs.layerName) {}
72 JumpData& operator = (const JumpData& rhs)
74 if (&rhs==this) return *this;
75 relativeJump = rhs.relativeJump;
76 slideNum = rhs.slideNum;
77 layerNum = rhs.layerNum;
78 slideName = rhs.slideName;
79 layerName = rhs.layerName;
83 META_Object(osgPresentation, JumpData);
85 bool requiresJump() const
87 if (!slideName.empty() || !layerName.empty()) return true;
88 return relativeJump ? (slideNum!=0 || layerNum!=0) : true;
91 bool jump(SlideEventHandler* seh) const;
93 void setRelativeJump(bool flag) { relativeJump = flag; }
94 bool getRelativeJump() const { return relativeJump; }
96 void setSlideNum(int num) { slideNum = num; }
97 int getSlideNum() const { return slideNum; }
99 void setLayerNum(int num) { layerNum = num; }
100 int getLayerNum() const { return layerNum; }
102 void setSlideName(const std::string& name) { slideName = name; }
103 const std::string& getSlideName() const { return slideName; }
105 void setLayerName(const std::string& name) { layerName = name; }
106 const std::string& getLayerName() const { return layerName; }
112 std::string slideName;
113 std::string layerName;
117struct HomePosition : public osg::Object
121 center(0.0, 0.0, 0.0),
124 HomePosition(const osg::Vec3& in_eye, const osg::Vec3& in_center, const osg::Vec3& in_up):
129 HomePosition(const HomePosition& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
130 osg::Object(rhs, copyop),
135 HomePosition& operator = (const HomePosition& rhs)
137 if (&rhs==this) return *this;
144 META_Object(osgPresentation, HomePosition);
146 void setEye(const osg::Vec3d& e) { eye = e; }
147 const osg::Vec3d& getEye() const { return eye; }
149 void setCenter(const osg::Vec3d& c) { center = c; }
150 const osg::Vec3d& getCenter() const { return center; }
152 void setUp(const osg::Vec3d& u) { up = u; }
153 const osg::Vec3d& getUp() const { return up; }
160struct KeyPosition : public osg::Object
162 KeyPosition(unsigned int key=0, float x=FLT_MAX, float y=FLT_MAX, bool forward_to_devices = false):
163 _key((osgGA::GUIEventAdapter::KeySymbol)key),
166 _forwardToDevices(forward_to_devices) {}
168 KeyPosition(const KeyPosition& rhs, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):
169 osg::Object(rhs, copyop),
173 _forwardToDevices(rhs._forwardToDevices) {}
175 META_Object(osgPresentation, KeyPosition);
177 KeyPosition& operator = (const KeyPosition& rhs)
179 if (&rhs==this) return *this;
183 _forwardToDevices = rhs._forwardToDevices;
187 void set(unsigned int key=0, float x=FLT_MAX, float y=FLT_MAX, bool forward_to_devices = false)
189 _key = (osgGA::GUIEventAdapter::KeySymbol)key;
192 _forwardToDevices = forward_to_devices;
195 void setKey(int key) { _key = static_cast<osgGA::GUIEventAdapter::KeySymbol>(key); }
196 int getKey() const { return _key; }
198 void setX(float x) { _x = x; }
199 float getX() const { return _x; }
201 void setY(float y) { _y = y; }
202 float getY() const { return _y; }
204 void setForwardToDevices(bool flag) { _forwardToDevices = flag; }
205 bool getForwardToDevices() const { return _forwardToDevices; }
208 osgGA::GUIEventAdapter::KeySymbol _key;
211 bool _forwardToDevices;
214struct LayerCallback : public virtual osg::Referenced
216 virtual void operator() (osg::Node* node) const = 0;
219struct OSGPRESENTATION_EXPORT LayerAttributes : public virtual osg::Referenced
221 LayerAttributes():_duration(0) {}
222 LayerAttributes(double in_duration):_duration(in_duration) {}
224 void setDuration(double duration) { _duration = duration; }
225 double getDuration() const { return _duration; }
227 typedef std::vector<KeyPosition> Keys;
228 typedef std::vector<std::string> RunStrings;
230 void setKeys(const Keys& keys) { _keys = keys; }
231 const Keys& getKeys() const { return _keys; }
233 void addKey(const KeyPosition& kp) { _keys.push_back(kp); }
235 void setRunStrings(const RunStrings& runStrings) { _runStrings = runStrings; }
236 const RunStrings& getRunStrings() const { return _runStrings; }
238 void addRunString(const std::string& runString) { _runStrings.push_back(runString); }
240 void setJump(const JumpData& jumpData) { _jumpData = jumpData; }
241 const JumpData& getJumpData() const { return _jumpData; }
245 RunStrings _runStrings;
248 void addEnterCallback(LayerCallback* lc) { _enterLayerCallbacks.push_back(lc); }
249 void addLeaveCallback(LayerCallback* lc) { _leaveLayerCallbacks.push_back(lc); }
251 void callEnterCallbacks(osg::Node* node);
252 void callLeaveCallbacks(osg::Node* node);
254 typedef std::list< osg::ref_ptr<LayerCallback> > LayerCallbacks;
255 LayerCallbacks _enterLayerCallbacks;
256 LayerCallbacks _leaveLayerCallbacks;
259struct FilePathData : public virtual osg::Referenced
261 FilePathData(const osgDB::FilePathList& fpl):filePathList(fpl) {}
263 osgDB::FilePathList filePathList;
267struct dereference_less
269 template<class T, class U>
270 inline bool operator() (const T& lhs,const U& rhs) const
276struct ObjectOperator : public osg::Referenced
278 inline bool operator < (const ObjectOperator& rhs) const { return ptr() < rhs.ptr(); }
280 virtual void* ptr() const = 0;
282 virtual void enter(SlideEventHandler*) = 0;
283 virtual void frame(SlideEventHandler*) {} ;
284 virtual void maintain(SlideEventHandler*) = 0;
285 virtual void leave(SlideEventHandler*) = 0;
286 virtual void setPause(SlideEventHandler*, bool pause) = 0;
287 virtual void reset(SlideEventHandler*) = 0;
289 virtual ~ObjectOperator() {}
292class OSGPRESENTATION_EXPORT ActiveOperators
298 void collect(osg::Node* incomingNode, osg::NodeVisitor::TraversalMode tm = osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
300 void process(SlideEventHandler* seh);
302 void frame(SlideEventHandler*);
304 void setPause(SlideEventHandler* seh, bool pause);
305 bool getPause() const { return _pause; }
307 void reset(SlideEventHandler* seh);
309 typedef std::set< osg::ref_ptr<ObjectOperator>, dereference_less > OperatorList;
313 void processOutgoing(SlideEventHandler* seh);
314 void processIncoming(SlideEventHandler* seh);
315 void processMaintained(SlideEventHandler* seh);
319 OperatorList _previous;
320 OperatorList _current;
322 OperatorList _outgoing;
323 OperatorList _incoming;
324 OperatorList _maintained;
328class OSGPRESENTATION_EXPORT SlideEventHandler : public osgGA::GUIEventHandler
332 SlideEventHandler(osgViewer::Viewer* viewer=0);
334 SlideEventHandler(const SlideEventHandler& seh,const osg::CopyOp& copyop);
336 static SlideEventHandler* instance();
338 META_Object(osgPresentation,SlideEventHandler);
340 void set(osg::Node* model);
342 virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
344 virtual void getUsage(osg::ApplicationUsage& usage) const;
346 osgViewer::Viewer* getViewer() { return _viewer.get(); }
348 osg::Switch* getPresentationSwitch() { return _presentationSwitch.get(); }
357 void compileSlide(unsigned int slideNum);
358 void releaseSlide(unsigned int slideNum);
360 unsigned int getNumSlides();
362 int getActiveSlide() const { return _activeSlide; }
363 int getActiveLayer() const { return _activeLayer; }
365 osg::Switch* getSlide(int slideNum);
366 osg::Node* getLayer(int slideNum, int layerNum);
368 bool selectSlide(int slideNum,int layerNum=FIRST_POSITION);
369 bool selectLayer(int layerNum);
371 bool nextLayerOrSlide();
372 bool previousLayerOrSlide();
375 bool previousSlide();
378 bool previousLayer();
382 void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; }
383 bool getAutoSteppingActive() const { return _autoSteppingActive; }
385 void setTimeDelayBetweenSlides(double dt) { _timePerSlide = dt; }
386 double getTimeDelayBetweenSlides() const { return _timePerSlide; }
388 double getDuration(const osg::Node* node) const;
390 double getCurrentTimeDelayBetweenSlides() const;
392 void setReleaseAndCompileOnEachNewSlide(bool flag) { _releaseAndCompileOnEachNewSlide = flag; }
393 bool getReleaseAndCompileOnEachNewSlide() const { return _releaseAndCompileOnEachNewSlide; }
395 void setTimeDelayOnNewSlideWithMovies(float t) { _timeDelayOnNewSlideWithMovies = t; }
396 float getTimeDelayOnNewSlideWithMovies() const { return _timeDelayOnNewSlideWithMovies; }
398 void setLoopPresentation(bool loop) { _loopPresentation = loop; }
399 bool getLoopPresentation() const { return _loopPresentation; }
402 void dispatchEvent(const KeyPosition& keyPosition);
403 void dispatchEvent(osgGA::Event* event);
405 void forwardEventToDevices(osgGA::Event* event);
407 void setRequestReload(bool flag);
408 bool getRequestReload() const { return _requestReload; }
410 double getReferenceTime() const { return _referenceTime; }
412 virtual bool checkNeedToDoFrame();
416 ~SlideEventHandler() {}
418 bool home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa);
420 void updateAlpha(bool, bool, float x, float y);
421 void updateLight(float x, float y);
423 void updateOperators();
426 osg::observer_ptr<osgViewer::Viewer> _viewer;
428 osg::observer_ptr<osg::Switch> _showSwitch;
429 int _activePresentation;
431 osg::observer_ptr<osg::Switch> _presentationSwitch;
434 osg::observer_ptr<osg::Switch> _slideSwitch;
437 bool _firstTraversal;
438 double _referenceTime;
439 double _previousTime;
440 double _timePerSlide;
441 bool _autoSteppingActive;
442 bool _loopPresentation;
446 bool _updateLightActive;
447 bool _updateOpacityActive;
448 float _previousX, _previousY;
452 bool _releaseAndCompileOnEachNewSlide;
454 bool _firstSlideOrLayerChange;
455 osg::Timer_t _tickAtFirstSlideOrLayerChange;
456 osg::Timer_t _tickAtLastSlideOrLayerChange;
458 float _timeDelayOnNewSlideWithMovies;
460 double _minimumTimeBetweenKeyPresses;
461 double _timeLastKeyPresses;
463 ActiveOperators _activeOperators;
465 osg::ref_ptr<CompileSlideCallback> _compileSlideCallback;