#include "gui_mgr.hxx"
#include <Canvas/window.hxx>
-#include <Canvas/canvas.hxx>
+#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Viewer/CameraGroup.hxx>
#include <Viewer/renderer.hxx>
+#include <simgear/canvas/Canvas.hxx>
+#include <simgear/canvas/CanvasPlacement.hxx>
+
+#include <osg/BlendFunc>
#include <osgViewer/Viewer>
#include <osgGA/GUIEventHandler>
* Track a canvas placement on a window
*/
class WindowPlacement:
- public canvas::Placement
+ public simgear::canvas::Placement
{
public:
WindowPlacement( canvas::WindowPtr window,
- CanvasPtr canvas ):
+ simgear::canvas::CanvasPtr canvas ):
_window(window),
_canvas(canvas)
{}
virtual ~WindowPlacement()
{
canvas::WindowPtr window = _window.lock();
- CanvasPtr canvas = _canvas.lock();
+ simgear::canvas::CanvasPtr canvas = _canvas.lock();
if( window && canvas && canvas == window->getCanvas().lock() )
- window->setCanvas( CanvasPtr() );
+ window->setCanvas( simgear::canvas::CanvasPtr() );
}
private:
canvas::WindowWeakPtr _window;
- CanvasWeakPtr _canvas;
+ simgear::canvas::CanvasWeakPtr _canvas;
+};
+
+/**
+ * Store pointer to window as user data
+ */
+class WindowUserData:
+ public osg::Referenced
+{
+ public:
+ canvas::WindowWeakPtr window;
+ WindowUserData(canvas::WindowPtr window):
+ window(window)
+ {}
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
GUIMgr::GUIMgr():
- PropertyBasedMgr("/sim/gui/canvas", "window", &windowFactory),
+ PropertyBasedMgr( fgGetNode("/sim/gui/canvas", true),
+ "window",
+ &windowFactory ),
_event_handler( new GUIEventHandler(this) ),
_transform( new osg::MatrixTransform ),
- _geode_windows( new osg::Geode ),
_width(_props, "size[0]"),
- _height(_props, "size[1]"),
- _last_push(-1)
+ _height(_props, "size[1]")
{
_width = _height = -1;
osg::Camera* camera =
flightgear::getGUICamera( flightgear::CameraGroup::getDefault() );
assert(camera);
+ camera->addChild(_transform);
osg::Viewport* vp = camera->getViewport();
handleResize(vp->x(), vp->y(), vp->width(), vp->height());
- _transform->addChild(_geode_windows);
- camera->addChild(_transform);
-
- Canvas::addPlacementFactory
+ simgear::canvas::Canvas::addPlacementFactory
(
"window",
boost::bind(&GUIMgr::addPlacement, this, _1, _2)
);
+
+ osg::StateSet* stateSet = _transform->getOrCreateStateSet();
+ stateSet->setDataVariance(osg::Object::STATIC);
+ stateSet->setRenderBinDetails(1000, "RenderBin");
+
+ // speed optimization?
+ stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
+ stateSet->setAttribute(new osg::BlendFunc(
+ osg::BlendFunc::SRC_ALPHA,
+ osg::BlendFunc::ONE_MINUS_SRC_ALPHA)
+ );
+ stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
+ stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+ stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
+ stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
}
//------------------------------------------------------------------------------
}
//------------------------------------------------------------------------------
-void GUIMgr::elementCreated(PropertyBasedElementPtr element)
+void GUIMgr::elementCreated(simgear::PropertyBasedElementPtr element)
{
- _geode_windows->addDrawable
- (
- static_cast<canvas::Window*>(element.get())->getDrawable()
- );
+ canvas::WindowPtr window =
+ boost::static_pointer_cast<canvas::Window>(element);
+
+ size_t layer_index = std::max(0, window->getProps()->getIntValue("layer", 1));
+ osg::Group *layer = 0;
+
+ if( layer_index < _transform->getNumChildren() )
+ {
+ layer = _transform->getChild(layer_index)->asGroup();
+ assert(layer);
+ }
+ else
+ {
+ while( _transform->getNumChildren() <= layer_index )
+ {
+ layer = new osg::Group;
+ _transform->addChild(layer);
+ }
+ }
+ window->getGroup()->setUserData(new WindowUserData(window));
+ layer->addChild(window->getGroup());
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
canvas::WindowPtr GUIMgr::getWindow(size_t i)
{
- return boost::shared_static_cast<canvas::Window>(_elements[i]);
+ return boost::static_pointer_cast<canvas::Window>(_elements[i]);
}
//------------------------------------------------------------------------------
-canvas::Placements GUIMgr::addPlacement( const SGPropertyNode* node,
- CanvasPtr canvas )
+simgear::canvas::Placements
+GUIMgr::addPlacement( const SGPropertyNode* node,
+ simgear::canvas::CanvasPtr canvas )
{
int placement_index = node->getIntValue("index", -1);
- canvas::Placements placements;
+ simgear::canvas::Placements placements;
for( size_t i = 0; i < _elements.size(); ++i )
{
- if( placement_index > 0 && static_cast<int>(i) != placement_index )
+ if( placement_index >= 0 && static_cast<int>(i) != placement_index )
continue;
canvas::WindowPtr window = getWindow(i);
window->setCanvas(canvas);
placements.push_back(
- canvas::PlacementPtr(new WindowPlacement(window, canvas))
+ simgear::canvas::PlacementPtr(new WindowPlacement(window, canvas))
);
}
return placements;
//------------------------------------------------------------------------------
bool GUIMgr::handleMouse(const osgGA::GUIEventAdapter& ea)
{
- canvas::MouseEvent event( ea.getEventType() );
+ if( !_transform->getNumChildren() )
+ return false;
+
+ simgear::canvas::MouseEvent event( ea.getEventType() );
event.x = 0.5 * (ea.getXnormalized() + 1) * _width + 0.5;
event.y = 0.5 * (ea.getYnormalized() + 1) * _height + 0.5;
event.mod = ea.getModKeyMask();
event.scroll = ea.getScrollingMotion();
- int window_at_cursor = -1;
- for( size_t i = 0; i < _elements.size(); ++i )
+ canvas::WindowPtr window_at_cursor;
+ for( int i = _transform->getNumChildren() - 1; i >= 0; --i )
{
- if( _elements[i]
- && getWindow(i)->getRegion().contains(event.x, event.y) )
+ osg::Group *layer = _transform->getChild(i)->asGroup();
+ assert(layer);
+ if( !layer->getNumChildren() )
+ continue;
+
+ for( int j = layer->getNumChildren() - 1; j >= 0; --j )
{
- window_at_cursor = i;
- break;
+ assert(layer->getChild(j)->getUserData());
+ canvas::WindowPtr window =
+ static_cast<WindowUserData*>(layer->getChild(j)->getUserData())
+ ->window.lock();
+ if( window->getRegion().contains(event.x, event.y) )
+ {
+ window_at_cursor = window;
+ break;
+ }
}
+
+ if( window_at_cursor )
+ break;
}
- int target_window = window_at_cursor;
+ canvas::WindowPtr target_window = window_at_cursor;
switch( ea.getEventType() )
{
case osgGA::GUIEventAdapter::PUSH:
break;
case osgGA::GUIEventAdapter::RELEASE:
- if( _last_push < 0 )
- return false;
-
- target_window = _last_push;
- _last_push = -1;
+ target_window = _last_push.lock();
+ _last_push.reset();
break;
case osgGA::GUIEventAdapter::DRAG:
- target_window = _last_push;
+ target_window = _last_push.lock();
break;
default:
return false;
}
- if( target_window >= 0 )
+ if( target_window )
{
- canvas::WindowPtr window = getWindow(target_window);
-
event.dx = event.x - _last_x;
event.dy = event.y - _last_y;
_last_y = event.y;
// Let the event position be always relative to the top left window corner
- event.x -= window->getRegion().x();
- event.y -= window->getRegion().y();
+ event.x -= target_window->getRegion().x();
+ event.y -= target_window->getRegion().y();
- return window->handleMouseEvent(event);
+ return target_window->handleMouseEvent(event);
}
else
return false;