X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fcanvas%2FCanvas.cxx;h=c7898b4535df604b07de4b0ccda9fa545af708af;hb=23413b47818b042620eeeaf306ffe6d1ae81852d;hp=9873ba6d09c8b40fc88eef0a5a74efaef31286c8;hpb=d332da06057f923858097a607ecf868e81c00d0d;p=simgear.git diff --git a/simgear/canvas/Canvas.cxx b/simgear/canvas/Canvas.cxx index 9873ba6d..c7898b45 100644 --- a/simgear/canvas/Canvas.cxx +++ b/simgear/canvas/Canvas.cxx @@ -19,8 +19,8 @@ #include "Canvas.hxx" #include "CanvasEventManager.hxx" #include "CanvasEventVisitor.hxx" -#include -#include +#include "CanvasPlacement.hxx" +#include #include #include @@ -48,8 +48,12 @@ namespace canvas void Canvas::CullCallback::operator()( osg::Node* node, osg::NodeVisitor* nv ) { - if( (nv->getTraversalMask() & simgear::MODEL_BIT) && !_canvas.expired() ) - _canvas.lock()->enableRendering(); + if( (nv->getTraversalMask() & simgear::MODEL_BIT) ) + { + CanvasPtr canvas = _canvas.lock(); + if( canvas ) + canvas->enableRendering(); + } traverse(node, nv); } @@ -72,6 +76,13 @@ namespace canvas { _status = 0; setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y); + + _root_group.reset( new Group(this, _node) ); + + // Remove automatically created property listener as we forward them on our + // own + _root_group->removeListener(); + _cull_callback = new CullCallback(this); } //---------------------------------------------------------------------------- @@ -180,6 +191,14 @@ namespace canvas return _root_group; } + //---------------------------------------------------------------------------- + void Canvas::setLayout(const LayoutRef& layout) + { + _layout = layout; + _layout->setCanvas(this); + _status |= LAYOUT_DIRTY; + } + //---------------------------------------------------------------------------- void Canvas::enableRendering(bool force) { @@ -191,11 +210,10 @@ namespace canvas //---------------------------------------------------------------------------- void Canvas::update(double delta_time_sec) { - if( (!_texture.serviceable() && _status != STATUS_DIRTY) - || (_status & CREATE_FAILED) ) + if( _status & (CREATE_FAILED | MISSING_SIZE) ) return; - if( _status == STATUS_DIRTY ) + if( _status & STATUS_DIRTY ) { _texture.setSize(_size_x, _size_y); @@ -237,23 +255,36 @@ namespace canvas } } + if( _layout ) + { + if( (_status & LAYOUT_DIRTY) ) + { + _layout->setGeometry(SGRecti(0, 0, _view_width, _view_height)); + _status &= ~LAYOUT_DIRTY; + } + else + _layout->update(); + } + if( _visible || _render_always ) { - BOOST_FOREACH(CanvasWeakPtr canvas, _child_canvases) + BOOST_FOREACH(CanvasWeakPtr canvas_weak, _child_canvases) { // TODO should we check if the image the child canvas is displayed // within is really visible? - if( !canvas.expired() ) - canvas.lock()->_visible = true; + CanvasPtr canvas = canvas_weak.lock(); + if( canvas ) + canvas->_visible = true; } if( _render_dirty ) { // Also mark all canvases this canvas is displayed within as dirty - BOOST_FOREACH(CanvasWeakPtr canvas, _parent_canvases) + BOOST_FOREACH(CanvasWeakPtr canvas_weak, _parent_canvases) { - if( !canvas.expired() ) - canvas.lock()->_render_dirty = true; + CanvasPtr canvas = canvas_weak.lock(); + if( canvas ) + canvas->_render_dirty = true; } } @@ -296,11 +327,7 @@ namespace canvas if( placement_factory != _placement_factories.end() ) { Placements& placements = _placements[ node->getIndex() ] = - placement_factory->second - ( - node, - boost::static_pointer_cast(_self.lock()) - ); + placement_factory->second(node, this); node->setStringValue ( "status-msg", @@ -317,11 +344,20 @@ namespace canvas const EventListener& cb ) { if( !_root_group.get() ) - throw std::runtime_error("Canvas::AddEventListener: no root group!"); + throw std::runtime_error("Canvas::addEventListener: no root group!"); return _root_group->addEventListener(type, cb); } + //---------------------------------------------------------------------------- + bool Canvas::dispatchEvent(const EventPtr& event) + { + if( !_root_group.get() ) + throw std::runtime_error("Canvas::dispatchEvent: no root group!"); + + return _root_group->dispatchEvent(event); + } + //---------------------------------------------------------------------------- void Canvas::setSizeX(int sx) { @@ -374,6 +410,7 @@ namespace canvas if( _view_width == w ) return; _view_width = w; + _status |= LAYOUT_DIRTY; _texture.setViewSize(_view_width, _view_height); } @@ -384,6 +421,7 @@ namespace canvas if( _view_height == h ) return; _view_height = h; + _status |= LAYOUT_DIRTY; _texture.setViewSize(_view_width, _view_height); } @@ -409,7 +447,7 @@ namespace canvas //---------------------------------------------------------------------------- bool Canvas::handleMouseEvent(const MouseEventPtr& event) { - if( !_root_group.get() ) + if( !_root_group ) return false; EventVisitor visitor( EventVisitor::TRAVERSE_DOWN, @@ -421,6 +459,13 @@ namespace canvas return _event_manager->handleEvent(event, visitor.getPropagationPath()); } + //---------------------------------------------------------------------------- + bool Canvas::propagateEvent( EventPtr const& event, + EventPropagationPath const& path ) + { + return _event_manager->propagateEvent(event, path); + } + //---------------------------------------------------------------------------- void Canvas::childAdded( SGPropertyNode * parent, SGPropertyNode * child ) @@ -452,7 +497,10 @@ namespace canvas //---------------------------------------------------------------------------- void Canvas::valueChanged(SGPropertyNode* node) { - if( boost::starts_with(node->getNameString(), "status") ) + const std::string& name = node->getNameString(); + + if( boost::starts_with(name, "status") + || boost::starts_with(name, "data-") ) return; _render_dirty = true; @@ -491,7 +539,7 @@ namespace canvas } else if( node->getParent() == _node ) { - if( node->getNameString() == "background" ) + if( name == "background" ) { osg::Vec4 color; if( _texture.getCamera() && parseColor(node->getStringValue(), color) ) @@ -500,35 +548,41 @@ namespace canvas _render_dirty = true; } } - else if( node->getNameString() == "mipmapping" - || node->getNameString() == "coverage-samples" - || node->getNameString() == "color-samples" ) + else if( name == "mipmapping" + || name == "coverage-samples" + || name == "color-samples" ) { _sampling_dirty = true; } - else if( node->getNameString() == "additive-blend" ) + else if( name == "additive-blend" ) { _texture.useAdditiveBlend( node->getBoolValue() ); } - else if( node->getNameString() == "render-always" ) + else if( name == "render-always" ) { _render_always = node->getBoolValue(); } - else if( node->getNameString() == "size" ) + else if( name == "size" ) { if( node->getIndex() == 0 ) setSizeX( node->getIntValue() ); else if( node->getIndex() == 1 ) setSizeY( node->getIntValue() ); } - else if( node->getNameString() == "view" ) + else if( name == "update" ) + { + if( _root_group ) + _root_group->update(0); + return update(0); + } + else if( name == "view" ) { if( node->getIndex() == 0 ) setViewWidth( node->getIntValue() ); else if( node->getIndex() == 1 ) setViewHeight( node->getIntValue() ); } - else if( node->getNameString() == "freeze" ) + else if( name == "freeze" ) _texture.setRender( node->getBoolValue() ); else handled = false; @@ -613,23 +667,6 @@ namespace canvas return _system_adapter; } - //---------------------------------------------------------------------------- - void Canvas::setSelf(const PropertyBasedElementPtr& self) - { - PropertyBasedElement::setSelf(self); - - CanvasPtr canvas = boost::static_pointer_cast(self); - - _root_group.reset( new Group(canvas, _node) ); - _root_group->setSelf(_root_group); - - // Remove automatically created property listener as we forward them on our - // own - _root_group->removeListener(); - - _cull_callback = new CullCallback(canvas); - } - //---------------------------------------------------------------------------- void Canvas::setStatusFlags(unsigned int flags, bool set) { @@ -646,7 +683,7 @@ namespace canvas _status_msg = "Missing size-y"; else if( _status & CREATE_FAILED ) _status_msg = "Creating render target failed"; - else if( _status == STATUS_DIRTY ) + else if( _status & STATUS_DIRTY ) _status_msg = "Creation pending..."; else _status_msg = "Ok";