// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "window.hxx"
-#include <Canvas/canvas.hxx>
+#include <simgear/canvas/Canvas.hxx>
-#include <osg/BlendFunc>
-#include <osg/Geometry>
-#include <osg/Texture2D>
#include <osgGA/GUIEventHandler>
-/**
- * Callback to enable/disable rendering of canvas displayed inside windows
- */
-class CullCallback:
- public osg::Drawable::CullCallback
-{
- public:
- CullCallback(Canvas::CameraCullCallback* camera_cull);
-
- private:
- Canvas::CameraCullCallback *_camera_cull;
-
- virtual bool cull( osg::NodeVisitor* nv,
- osg::Drawable* drawable,
- osg::RenderInfo* renderInfo ) const;
-};
-
-//------------------------------------------------------------------------------
-CullCallback::CullCallback(Canvas::CameraCullCallback* camera_cull):
- _camera_cull( camera_cull )
-{
-
-}
-
-//------------------------------------------------------------------------------
-bool CullCallback::cull( osg::NodeVisitor* nv,
- osg::Drawable* drawable,
- osg::RenderInfo* renderInfo ) const
-{
- _camera_cull->enableRendering();
- return false;
-}
+#include <boost/foreach.hpp>
namespace canvas
{
//----------------------------------------------------------------------------
Window::Window(SGPropertyNode* node):
PropertyBasedElement(node),
- _dirty(true),
- _geometry( new osg::Geometry ),
- _vertices( new osg::Vec3Array(4) ),
- _tex_coords( new osg::Vec2Array(4) ),
- _x(node, "x"),
- _y(node, "y"),
- _width(node, "size[0]"),
- _height(node, "size[1]")
+ _image( simgear::canvas::CanvasPtr(),
+ node,
+ simgear::canvas::Style() ),
+ _resizable(false),
+ _capture_events(true),
+ _resize_top(node, "resize-top"),
+ _resize_right(node, "resize-right"),
+ _resize_bottom(node, "resize-bottom"),
+ _resize_left(node, "resize-left"),
+ _resize_status(node, "resize-status")
{
- _x = 50;
- _y = 100;
- _width = 400;
- _height = 300;
-
- _geometry->setVertexArray(_vertices);
- _geometry->setTexCoordArray(0,_tex_coords);
-
- osg::Vec4Array* colors = new osg::Vec4Array(1);
- (*colors)[0].set(1.0f,1.0f,1.0,1.0f);
- _geometry->setColorArray(colors);
- _geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
-
- _geometry->addPrimitiveSet(
- new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)
- );
- _geometry->setDataVariance(osg::Object::DYNAMIC);
-
- osg::StateSet* stateSet = _geometry->getOrCreateStateSet();
- 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);
- stateSet->setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON);
+ _image.removeListener();
+
+ // TODO probably better remove default position and size
+ node->setFloatValue("x", 50);
+ node->setFloatValue("y", 100);
+ node->setFloatValue("size[0]", 400);
+ node->setFloatValue("size[1]", 300);
+
+ node->setFloatValue("source/right", 1);
+ node->setFloatValue("source/bottom", 1);
+ node->setBoolValue("source/normalized", true);
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void Window::update(double delta_time_sec)
{
- if( !_dirty )
- return;
- _dirty = false;
+ _image.update(delta_time_sec);
+ }
- _region.set(_x, _y, _width, _height);
+ //----------------------------------------------------------------------------
+ void Window::valueChanged(SGPropertyNode * node)
+ {
+ bool handled = false;
+ if( node->getParent() == _node )
+ {
+ handled = true;
+ if( node->getNameString() == "raise-top" )
+ doRaise(node);
+ else if( node->getNameString() == "resize" )
+ _resizable = node->getBoolValue();
+ else if( node->getNameString() == "capture-events" )
+ _capture_events = node->getBoolValue();
+ else
+ handled = false;
+ }
+
+ if( !handled )
+ _image.valueChanged(node);
+ }
- int z = 0; // TODO do we need to use z for depth ordering?
+ //----------------------------------------------------------------------------
+ osg::Group* Window::getGroup()
+ {
+ return _image.getMatrixTransform();
+ }
- (*_vertices)[0].set(_region.l(), _region.t(), z);
- (*_vertices)[1].set(_region.r(), _region.t(), z);
- (*_vertices)[2].set(_region.r(), _region.b(), z);
- (*_vertices)[3].set(_region.l(), _region.b(), z);
+ //----------------------------------------------------------------------------
+ const SGRect<float>& Window::getRegion() const
+ {
+ return _image.getRegion();
+ }
- float l = 0, t = 1, b = 0, r = 1;
- (*_tex_coords)[0].set(l,t);
- (*_tex_coords)[1].set(r,t);
- (*_tex_coords)[2].set(r,b);
- (*_tex_coords)[3].set(l,b);
+ //----------------------------------------------------------------------------
+ void Window::setCanvas(simgear::canvas::CanvasPtr canvas)
+ {
+ _image.setSrcCanvas(canvas);
+ }
- _geometry->dirtyDisplayList();
+ //----------------------------------------------------------------------------
+ simgear::canvas::CanvasWeakPtr Window::getCanvas() const
+ {
+ return _image.getSrcCanvas();
}
//----------------------------------------------------------------------------
- void Window::valueChanged (SGPropertyNode * node)
+ bool Window::isVisible() const
{
- if( node->getParent() != _node )
- return;
+ return _image.isVisible();
+ }
- const std::string& name = node->getNameString();
- if( name == "x" || name == "y" || name == "size" )
- _dirty = true;
+ //----------------------------------------------------------------------------
+ bool Window::isResizable() const
+ {
+ return _resizable;
}
//----------------------------------------------------------------------------
- void Window::setCanvas(CanvasPtr canvas)
+ bool Window::isCapturingEvents() const
{
- _canvas = canvas;
- _geometry->getOrCreateStateSet()
- ->setTextureAttribute(0, canvas ? canvas->getTexture() : 0);
- _geometry->dirtyDisplayList();
- _geometry->setCullCallback(
- canvas ? new CullCallback(canvas->getCameraCullCallback()) : 0
- );
+ return _capture_events;
}
//----------------------------------------------------------------------------
- CanvasWeakPtr Window::getCanvas() const
+ bool Window::handleMouseEvent(const simgear::canvas::MouseEventPtr& event)
{
- return _canvas;
+ return _image.handleEvent(event);
}
//----------------------------------------------------------------------------
- bool Window::handleMouseEvent(const MouseEvent& event)
+ void Window::handleResize(uint8_t mode, const osg::Vec2f& delta)
{
- if( !_canvas.expired() )
- return _canvas.lock()->handleMouseEvent(event);
- else
- return false;
+ if( mode == NONE )
+ {
+ _resize_status = 0;
+ return;
+ }
+ else if( mode & INIT )
+ {
+ _resize_top = getRegion().t();
+ _resize_right = getRegion().r();
+ _resize_bottom = getRegion().b();
+ _resize_left = getRegion().l();
+ _resize_status = 1;
+ }
+
+ if( mode & BOTTOM )
+ _resize_bottom += delta.y();
+ else if( mode & TOP )
+ _resize_top += delta.y();
+
+ if( mode & canvas::Window::RIGHT )
+ _resize_right += delta.x();
+ else if( mode & canvas::Window::LEFT )
+ _resize_left += delta.x();
+ }
+
+ //----------------------------------------------------------------------------
+ void Window::doRaise(SGPropertyNode* node_raise)
+ {
+ if( node_raise && !node_raise->getBoolValue() )
+ return;
+
+ BOOST_FOREACH(osg::Group* parent, getGroup()->getParents())
+ {
+ // Remove window...
+ parent->removeChild(getGroup());
+
+ // ...and add again as topmost window
+ parent->addChild(getGroup());
+ }
+
+ if( node_raise )
+ node_raise->setBoolValue(false);
}
} // namespace canvas