void WgPackList::_renderPatches( WgGfxDevice * pDevice, const WgRect& _canvas, const WgRect& _window, WgPatches * _pPatches ) { // We start by eliminating dirt outside our geometry WgPatches patches( _pPatches->Size() ); // TODO: Optimize by pre-allocating? for( const WgRect * pRect = _pPatches->Begin() ; pRect != _pPatches->End() ; pRect++ ) { if( _canvas.IntersectsWith( *pRect ) ) patches.Push( WgRect(*pRect,_canvas) ); } // Render container itself for( const WgRect * pRect = patches.Begin() ; pRect != patches.End() ; pRect++ ) _onRender(pDevice, _canvas, _window, *pRect ); // Render children WgRect dirtBounds = patches.Union(); { WgRect childGeo; WgPackListHook * p = (WgPackListHook*)_firstHookWithGeo( childGeo ); while(p) { WgRect canvas = childGeo + _canvas.Pos(); if( p->_isVisible() && canvas.IntersectsWith( dirtBounds ) ) p->_widget()->_renderPatches( pDevice, canvas, canvas, &patches ); p = (WgPackListHook*) _nextHookWithGeo( childGeo, p ); } } // Render header if( m_header.m_height != 0 ) { bool bInvertedSort = (m_sortOrder == WG_SORT_DESCENDING); WgRect canvas = _headerGeo() + _canvas.Pos(); for( const WgRect * pRect = patches.Begin() ; pRect != patches.End() ; pRect++ ) _renderHeader( pDevice, canvas, *pRect, m_header.m_pSkin, &m_header.label, &m_header.icon, &m_header.arrow, m_header.m_state, true, bInvertedSort ); } // Render Lasso if( m_pLassoSkin && m_lassoBegin != m_lassoEnd ) { WgRect lasso( m_lassoBegin, m_lassoEnd ); lasso += _canvas.Pos(); for( const WgRect * pRect = patches.Begin() ; pRect != patches.End() ; pRect++ ) m_pLassoSkin->Render( pDevice, lasso, m_state, WgRect( lasso, *pRect ) ); } }
void WgStackPanel::_onRenderRequested( WgVectorHook * _pHook, const WgRect& _rect ) { WgStackHook * pHook = static_cast<WgStackHook*>(_pHook); if( !pHook->IsVisible() ) return; // Put our rectangle into patches WgRect rect = _rect + pHook->_getGeo(WgRect(0,0,m_size)).Pos(); WgPatches patches; patches.Add( rect ); // Remove portions of patches that are covered by opaque upper siblings WgStackHook * pCover = ((WgStackHook*)pHook)->_next(); while( pCover ) { WgRect geo = pCover->_getGeo(m_size); if( pCover->IsVisible() && geo.IntersectsWith( rect ) ) pCover->_widget()->_onMaskPatches( patches, geo, WgRect(0,0,65536,65536 ), _getBlendMode() ); pCover = pCover->_next(); } // Make request render calls for( const WgRect * pRect = patches.Begin() ; pRect < patches.End() ; pRect++ ) _requestRender( * pRect ); }
void WgPackList::_onLassoUpdated( const WgRect& oldLasso, const WgRect& newLasso ) { // Get out content area WgRect listArea = _listArea(); // Check if our lassos are inside content area or not. bool bOldLassoInside = false; bool bNewLassoInside = false; if( oldLasso.IntersectsWith(listArea ) ) bOldLassoInside = true; if( newLasso.IntersectsWith(listArea ) ) bNewLassoInside = true; if( !bOldLassoInside && !bNewLassoInside ) return; // None of the lassos inside content. // Get first/last entries marked by old/new lasso int oldOfs1, oldOfs2; int newOfs1, newOfs2; if( m_bHorizontal ) { oldOfs1 = oldLasso.x - listArea.x; oldOfs2 = oldLasso.x + oldLasso.w - listArea.x; newOfs1 = newLasso.x - listArea.x; newOfs2 = newLasso.x + newLasso.w - listArea.x; } else { oldOfs1 = oldLasso.y - listArea.y; oldOfs2 = oldLasso.y + oldLasso.h - listArea.y; newOfs1 = newLasso.y - listArea.y; newOfs2 = newLasso.y + newLasso.h - listArea.y; } int oldFirst = _getEntryAt( oldOfs1 ); int oldLast = _getEntryAt( oldOfs2 ); int newFirst = _getEntryAt( newOfs1 ); int newLast = _getEntryAt( newOfs2 ); // if( bOldLassoInside != bNewLassoInside ) { int beg, end; if( bNewLassoInside ) { beg = newFirst; end = newLast; } else { beg = oldFirst; end = oldLast; } _flipRange( m_hooks.Hook(beg), m_hooks.Hook(end), true ); } else { if( oldFirst != newFirst ) { int beg = WgMin(oldFirst,newFirst); int end = WgMax(oldFirst,newFirst)-1; _flipRange( m_hooks.Hook(beg), m_hooks.Hook(end), true ); } if( oldLast != newLast ) { int beg = WgMin(oldLast,newLast)+1; int end = WgMax(oldLast,newLast); _flipRange( m_hooks.Hook(beg), m_hooks.Hook(end), true ); } } }