X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fcanvas%2FCanvas.cxx;h=c7898b4535df604b07de4b0ccda9fa545af708af;hb=23413b47818b042620eeeaf306ffe6d1ae81852d;hp=fa6712389c22ecaf2357cfb9b225f98f090ed63d;hpb=5320d0ecaa696eb2712598879a15ae505bb65e4f;p=simgear.git diff --git a/simgear/canvas/Canvas.cxx b/simgear/canvas/Canvas.cxx index fa671238..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,19 @@ 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); + } + + //---------------------------------------------------------------------------- + Canvas::~Canvas() + { + } //---------------------------------------------------------------------------- @@ -84,19 +101,6 @@ namespace canvas } } - //---------------------------------------------------------------------------- - void Canvas::setSystemAdapter(const SystemAdapterPtr& system_adapter) - { - _system_adapter = system_adapter; - _texture.setSystemAdapter(system_adapter); - } - - //---------------------------------------------------------------------------- - SystemAdapterPtr Canvas::getSystemAdapter() const - { - return _system_adapter; - } - //---------------------------------------------------------------------------- void Canvas::setCanvasMgr(CanvasMgr* canvas_mgr) { @@ -187,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) { @@ -198,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); @@ -221,6 +232,10 @@ namespace canvas osg::Camera* camera = _texture.getCamera(); + // TODO Allow custom render order? For now just keep in order with + // property tree. + camera->setRenderOrder(osg::Camera::PRE_RENDER, _node->getIndex()); + osg::Vec4 clear_color(0.0f, 0.0f, 0.0f , 1.0f); parseColor(_node->getStringValue("background"), clear_color); camera->setClearColor(clear_color); @@ -240,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; } } @@ -299,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", @@ -316,12 +340,22 @@ namespace canvas } //---------------------------------------------------------------------------- - naRef Canvas::addEventListener(const nasal::CallContext& ctx) + bool Canvas::addEventListener( const std::string& type, + const EventListener& cb ) { if( !_root_group.get() ) - naRuntimeError(ctx.c, "Canvas: No root group!"); + throw std::runtime_error("Canvas::addEventListener: no root group!"); - return _root_group->addEventListener(ctx); + 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); } //---------------------------------------------------------------------------- @@ -376,6 +410,7 @@ namespace canvas if( _view_width == w ) return; _view_width = w; + _status |= LAYOUT_DIRTY; _texture.setViewSize(_view_width, _view_height); } @@ -386,6 +421,7 @@ namespace canvas if( _view_height == h ) return; _view_height = h; + _status |= LAYOUT_DIRTY; _texture.setViewSize(_view_width, _view_height); } @@ -411,12 +447,11 @@ namespace canvas //---------------------------------------------------------------------------- bool Canvas::handleMouseEvent(const MouseEventPtr& event) { - if( !_root_group.get() ) + if( !_root_group ) return false; EventVisitor visitor( EventVisitor::TRAVERSE_DOWN, event->getClientPos(), - event->getDelta(), _root_group ); if( !_root_group->accept(visitor) ) return false; @@ -424,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 ) @@ -455,8 +497,10 @@ namespace canvas //---------------------------------------------------------------------------- void Canvas::valueChanged(SGPropertyNode* node) { - if( boost::starts_with(node->getNameString(), "status") - || node->getParent()->getNameString() == "bounding-box" ) + const std::string& name = node->getNameString(); + + if( boost::starts_with(name, "status") + || boost::starts_with(name, "data-") ) return; _render_dirty = true; @@ -495,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) ) @@ -504,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; @@ -583,27 +633,38 @@ namespace canvas ( SG_GENERAL, SG_WARN, - "Canvas::addPlacementFactory: replace existing factor for type " << type + "Canvas::addPlacementFactory: replace existing factory '" << type << "'" ); _placement_factories[type] = factory; } //---------------------------------------------------------------------------- - void Canvas::setSelf(const PropertyBasedElementPtr& self) + void Canvas::removePlacementFactory(const std::string& type) { - PropertyBasedElement::setSelf(self); - - CanvasPtr canvas = boost::static_pointer_cast(self); + PlacementFactoryMap::iterator it = _placement_factories.find(type); + if( it == _placement_factories.end() ) + SG_LOG + ( + SG_GENERAL, + SG_WARN, + "Canvas::removePlacementFactory: no such factory '" << type << "'" + ); + else + _placement_factories.erase(it); + } - _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(); + //---------------------------------------------------------------------------- + void Canvas::setSystemAdapter(const SystemAdapterPtr& system_adapter) + { + _system_adapter = system_adapter; + } - _cull_callback = new CullCallback(canvas); + //---------------------------------------------------------------------------- + SystemAdapterPtr Canvas::getSystemAdapter() + { + return _system_adapter; } //---------------------------------------------------------------------------- @@ -622,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"; @@ -630,6 +691,7 @@ namespace canvas //---------------------------------------------------------------------------- Canvas::PlacementFactoryMap Canvas::_placement_factories; + SystemAdapterPtr Canvas::_system_adapter; } // namespace canvas } // namespace simgear