Пример #1
0
	Widget * Container::_findWidget( const Coord& ofs, SearchMode mode )
	{
		Rect childGeo;
		Hook * pHook = _lastHookWithGeo( childGeo );
		Widget * pResult = 0;
	
		while( pHook && !pResult )
		{
			if( pHook->_isVisible() && childGeo.contains( ofs ) )
			{
				if( pHook->_widget()->isContainer() )
				{
					pResult = static_cast<Container*>(pHook->_widget())->_findWidget( ofs - childGeo.pos(), mode );
				}
				else if( mode == SearchMode::Geometry || pHook->_widget()->markTest( ofs - childGeo.pos() ) )
				{
						pResult = pHook->_widget();
				}
			}
			pHook = _prevHookWithGeo( childGeo, pHook );
		}
	
		// Check against ourselves
	
		if( !pResult && ( mode == SearchMode::Geometry || markTest(ofs)) )
			pResult = this;
			
		return pResult;
	}
Пример #2
0
	Widget * Container::_lastWidget() const 
	{ 
		Hook * p = _lastHook(); 
		if( p ) 
			return p->_widget(); 
		else 
			return 0; 
	}
Пример #3
0
	void Container::_collectPatches( Patches& container, const Rect& geo, const Rect& clip )
	{
		if( m_pSkin )
			container.add( Rect( geo, clip ) );
		else
		{
			Rect childGeo;
			Hook * p = _firstHookWithGeo( childGeo );
	
			while(p)
			{
				if( p->_isVisible() )
					p->_widget()->_collectPatches( container, childGeo + geo.pos(), clip );
				p = _nextHookWithGeo( childGeo, p );
			}
		}
	}
Пример #4
0
	void Container::_maskPatches( Patches& patches, const Rect& geo, const Rect& clip, BlendMode blendMode )
	{
		//TODO: Don't just check isOpaque() globally, check rect by rect.
		if( (m_bOpaque && blendMode == BlendMode::Blend) || blendMode == BlendMode::Replace)
			patches.sub( Rect(geo,clip) );
		else
		{
			Rect childGeo;
			Hook * p = _firstHookWithGeo( childGeo );
	
			while(p)
			{
				if( p->_isVisible() )
					p->_widget()->_maskPatches( patches, childGeo + geo.pos(), clip, blendMode );
				p = _nextHookWithGeo( childGeo, p );
			}
		}
	}
Пример #5
0
	void Container::_renderPatches( GfxDevice * pDevice, const Rect& _canvas, const Rect& _window, Patches * _pPatches )
	{
	
		// We start by eliminating dirt outside our geometry
	
		Patches 	patches( _pPatches->size() );								// TODO: Optimize by pre-allocating?
	
		for( const Rect * pRect = _pPatches->begin() ; pRect != _pPatches->end() ; pRect++ )
		{
			if( _canvas.intersectsWith( *pRect ) )
				patches.push( Rect(*pRect,_canvas) );
		}
	
	
		// Render container itself
		
		for( const Rect * pRect = patches.begin() ; pRect != patches.end() ; pRect++ )
			_render(pDevice, _canvas, _window, *pRect );
			
		
		// Render children
	
		Rect	dirtBounds = patches.getUnion();
		
		if( m_bSiblingsOverlap )
		{
	
			// Create WidgetRenderContext's for siblings that might get dirty patches
	
			std::vector<WidgetRenderContext> renderList;
	
			Rect childGeo;
			Hook * p = _firstHookWithGeo( childGeo );
			while(p)
			{
				Rect geo = childGeo + _canvas.pos();
	
				if( p->_isVisible() && geo.intersectsWith( dirtBounds ) )
					renderList.push_back( WidgetRenderContext(p->_widget(), geo ) );
	
				p = _nextHookWithGeo( childGeo, p );
			}
	
			// Go through WidgetRenderContexts in reverse order (topmost first), push and mask dirt
	
			for( int i = renderList.size()-1 ; i >= 0 ; i-- )
			{
				WidgetRenderContext * p = &renderList[i];
	
				p->patches.push( &patches );
	
				p->pWidget->_maskPatches( patches, p->geo, p->geo, pDevice->blendMode() );		//TODO: Need some optimizations here, grandchildren can be called repeatedly! Expensive!
	
				if( patches.isEmpty() )
					break;
			}
	
			// Go through WidgetRenderContexts and render the patches
	
			for( int i = 0 ; i < (int) renderList.size() ; i++ )
			{
				WidgetRenderContext * p = &renderList[i];
				p->pWidget->_renderPatches( pDevice, p->geo, p->geo, &p->patches );
			}
	
		}
		else
		{
			Rect childGeo;
			Hook * p = _firstHookWithGeo( childGeo );
	
			while(p)
			{
				Rect canvas = childGeo + _canvas.pos();
				if( p->_isVisible() && canvas.intersectsWith( dirtBounds ) )
					p->_widget()->_renderPatches( pDevice, canvas, canvas, &patches );
				p = _nextHookWithGeo( childGeo, p );
			}
	
		}
	}