OpenSceneGraph/examples/slideshow3D/SlideEventHandler.cpp
2003-07-23 15:12:52 +00:00

273 lines
7.7 KiB
C++

#include "SlideEventHandler.h"
class FindNamedSwitchVisitor : public osg::NodeVisitor
{
public:
FindNamedSwitchVisitor(const std::string& name):
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_name(name),
_switch(0) {}
void apply(osg::Switch& sw)
{
if (sw.getName().find(_name)!=std::string::npos)
{
_switch = &sw;
return; // note, no need to do traverse now we've located the relevant switch
}
traverse(sw);
}
std::string _name;
osg::Switch* _switch;
};
SlideEventHandler::SlideEventHandler():
_presentationSwitch(0),
_activeSlide(0),
_slideSwitch(0),
_activeLayer(0),
_firstTraversal(true),
_previousTime(-1.0f),
_timePerSlide(1.0),
_autoSteppingActive(false),
_loopPresentation(true),
_pause(false)
{
}
void SlideEventHandler::set(osg::Node* model)
{
FindNamedSwitchVisitor findPresentation("Presentation");
model->accept(findPresentation);
if (findPresentation._switch)
{
std::cout<<"Presentation '"<<model->getName()<<"'"<<std::endl;
_presentationSwitch = findPresentation._switch;
selectSlide(0);
}
else
{
std::cout<<"No presentation present in scene."<<std::endl;
_presentationSwitch = 0;
_activeSlide = 0;
FindNamedSwitchVisitor findSlide("Slide");
model->accept(findSlide);
if (findSlide._switch)
{
std::cout<<"Found presentation slide"<<findSlide._switch->getName()<<std::endl;
_slideSwitch = findSlide._switch;
selectLayer(0);
}
else
{
std::cout<<"No slides present in scene, unable to operate as a slideshow."<<std::endl;
}
}
}
bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
{
switch(ea.getEventType())
{
case(osgGA::GUIEventAdapter::FRAME):
{
if (_autoSteppingActive)
{
double time = ea.time();
if (_firstTraversal)
{
_firstTraversal = false;
_previousTime = time;
}
else if (time-_previousTime>_timePerSlide)
{
_previousTime = time;
nextLayerOrSlide();
}
}
}
case(osgGA::GUIEventAdapter::KEYDOWN):
{
if (ea.getKey()=='a')
{
_autoSteppingActive = !_autoSteppingActive;
_previousTime = ea.time();
return true;
}
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Home ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)
{
_autoSteppingActive = false;
selectSlide(0);
return true;
}
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_End ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)
{
_autoSteppingActive = false;
selectSlide(LAST_POSITION,LAST_POSITION);
return true;
}
else if (ea.getKey()=='n' ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Down ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down)
{
_autoSteppingActive = false;
nextLayerOrSlide();
return true;
}
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Up ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up)
{
_autoSteppingActive = false;
previousLayerOrSlide();
return true;
}
else if (ea.getKey()=='N' ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Right ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Down ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Down)
{
_autoSteppingActive = false;
nextSlide();
return true;
}
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Up ||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Up)
{
_autoSteppingActive = false;
previousSlide();
return true;
}
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Pause)
{
_pause = !_pause;
if (_pause) std::cout<<"Pause"<<std::endl;
else std::cout<<"End Pause"<<std::endl;
}
return false;
}
default:
return false;
}
}
void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
{
usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
usage.addKeyboardMouseBinding("n","Advance to next layer or slide");
usage.addKeyboardMouseBinding("p","Move to previous layer or slide");
}
bool SlideEventHandler::selectSlide(unsigned int slideNum,unsigned int layerNum)
{
if (!_presentationSwitch) return false;
if (slideNum==LAST_POSITION && _presentationSwitch->getNumChildren()>0)
{
slideNum = _presentationSwitch->getNumChildren()-1;
}
if (slideNum>=_presentationSwitch->getNumChildren()) return false;
_activeSlide = slideNum;
_presentationSwitch->setSingleChildOn(_activeSlide);
//std::cout<<"Selected slide '"<<_presentationSwitch->getChild(_activeSlide)->getName()<<"'"<<std::endl;
FindNamedSwitchVisitor findSlide("Slide");
_presentationSwitch->getChild(_activeSlide)->accept(findSlide);
if (findSlide._switch)
{
//std::cout<<"Found slide '"<<findSlide._switch->getName()<<"'"<<std::endl;
_slideSwitch = findSlide._switch;
return selectLayer(layerNum);
}
else
{
//std::cout<<"Not found slide"<<std::endl;
}
return false;
}
bool SlideEventHandler::selectLayer(unsigned int layerNum)
{
if (!_slideSwitch) return false;
if (layerNum==LAST_POSITION && _slideSwitch->getNumChildren()>0)
{
layerNum = _slideSwitch->getNumChildren()-1;
}
if (layerNum>=_slideSwitch->getNumChildren()) return false;
_activeLayer = layerNum;
_slideSwitch->setSingleChildOn(_activeLayer);
//std::cout<<"Selected layer '"<<_slideSwitch->getChild(_activeLayer)->getName()<<"' num="<<_activeLayer<< std::endl;
return true;
}
bool SlideEventHandler::nextLayerOrSlide()
{
if (nextLayer()) return true;
else return nextSlide();
}
bool SlideEventHandler::previousLayerOrSlide()
{
if (previousLayer()) return true;
else return previousSlide();
}
bool SlideEventHandler::nextSlide()
{
if (selectSlide(_activeSlide+1)) return true;
else if (_loopPresentation) return selectSlide(0);
else return false;
}
bool SlideEventHandler::previousSlide()
{
if (_activeSlide>0) return selectSlide(_activeSlide-1,LAST_POSITION);
else if (_loopPresentation && _presentationSwitch.valid()) return selectSlide(_presentationSwitch->getNumChildren()-1,LAST_POSITION);
else return false;
}
bool SlideEventHandler::nextLayer()
{
return selectLayer(_activeLayer+1);
}
bool SlideEventHandler::previousLayer()
{
if (_activeLayer>0) return selectLayer(_activeLayer-1);
else return false;
}