//____ _onRender() _____________________________________________________________ void WgTablePanel::_onRender( WgGfxDevice * pDevice, const WgRect& _canvas, const WgRect& _window, const WgRect& _clip ) { WgRect r = _canvas; WgRect clipView = _clip; if( r.w < _window.w ) r.w = _window.w; // Draw header (if any) if( m_bShowHeader && m_pHeaderGfx ) { WgRect headerArea( _canvas.x, _window.y, _canvas.w, m_pHeaderGfx->Height() ); WgRect r2 = headerArea; for( int i = 0 ; i < m_nColumns ; i++ ) { if( !m_pColumns[i].m_bVisible ) continue; // don't draw columns that are outside of the window if( r2.x >= _window.x + _window.w ) break; r2.w = m_pColumns[i].m_realWidth; //if( i == m_nColumns-1 && r2.x + r2.w < _window.x + _window.w ) if( i == m_nColumns-1 ) r2.w = _window.x + _window.w - r2.x; // Last column header stretches to end of tableview... WgMode mode = WG_MODE_NORMAL; if(&m_pColumns[i] == m_pMarkedHeader) mode = WG_MODE_MARKED; else if( i == m_lastSortColumn ) mode = WG_MODE_SPECIAL; pDevice->ClipBlitBlock( _clip, m_pHeaderGfx->GetBlock(mode,r2), r2 ); if( i == m_lastSortColumn && m_pAscendGfx && m_pDescendGfx ) { WgBlock block; if( m_lastSortColumnAscendStatus ) block = m_pAscendGfx->GetBlock(mode); else block = m_pDescendGfx->GetBlock(mode); WgRect dest = WgUtil::OrigoToRect( m_sortMarkerAlignment, r2.Size(), block.Size() ); dest += m_sortMarkerOfs; pDevice->ClipBlitBlock( _clip, block, dest ); } WgRect rText = r2; if( m_pHeaderGfx ) rText.Shrink( m_pHeaderGfx->Padding() ); m_pColumns[i]._getTextObj()->setProperties( m_pHeaderProps ); pDevice->PrintText( _clip, m_pColumns[i]._getTextObj(), rText ); r2.x += r2.w - 1; // HACK: Overlap last pixel to avoid double separator graphics between two headers } r.y += m_pHeaderGfx->Height(); // Modify clipping rectangle for view content (we don't want to draw over header) if( _clip.y < _window.y + m_pHeaderGfx->Height()) { int diff = _window.y + m_pHeaderGfx->Height() - _clip.y; clipView.y += diff; clipView.h -= diff; if( clipView.h < 1 ) return; } } // Start drawing cell contents. WgTableRow * pRow = m_rows.First(); int iRowColor = 0; // Skip rows that are above clipping area. r.y += m_cellPadding.top; while( pRow ) { if( pRow->IsVisible() ) { if( r.y + (int) pRow->Height() >= clipView.y ) break; r.y += pRow->Height() + m_cellPadding.Height(); iRowColor++; } pRow = pRow->Next(); } r.y -= m_cellPadding.top; // Draw cell contents for (at least partly) visible rows. while( pRow ) { if( !pRow->IsVisible() ) { pRow = pRow->Next(); continue; } if( r.y >= clipView.y + clipView.h ) break; r.h = pRow->Height() + m_cellPadding.Height(); WgRect u; if( u.Intersection( r, clipView ) ) { if( pRow->IsSelected() ) { if(HasSelectedRowBg() == true) pDevice->ClipBlitBlock(u, m_pSelectedRowGfx->GetBlock(WG_MODE_NORMAL,r), r ); else pDevice->Fill( u, m_selectedRowColor ); } else { if( m_nRowColors > 0 ) { WgColor color = m_pRowColors[ iRowColor % m_nRowColors ]; if( 0 != color.a ) pDevice->Fill( u, color ); } if( m_nRowBlocks > 0 ) { WgBlocksetPtr p = m_pRowBlocks[ iRowColor % m_nRowBlocks ]; if( p ) pDevice->ClipBlitBlock(u, p->GetBlock(WG_MODE_NORMAL,r), r ); } } } WgRect rc = r; rc.y += m_cellPadding.top; rc.h = pRow->Height(); for( int i = 0 ; i < m_nColumns ; i++ ) { WgTableHook * pHook = 0; if( pRow->m_nCells > i && pRow->m_pCells[i].Widget() != 0 ) pHook = &pRow->m_pCells[i]; // if( pHook == 0 ) //TODO: Make it right! // pHook = m_pColumns[i].m_pDefaultWidgetHook; if( m_pColumns[i].m_bVisible && pHook->IsVisible() && pHook->Widget() != 0 ) { // don't draw columns that are outside of the window if( rc.x >= _window.x + _window.w ) break; rc.w = m_pColumns[i].m_realWidth; if( i == m_nColumns-1 && rc.x + rc.w < _window.x + _window.w ) rc.w = _window.x + _window.w - rc.x; // Last column stretches to end of tableview... rc.x += m_cellPadding.left; rc.w -= m_cellPadding.Width(); WgRect clip2( rc, clipView ); // pHook->Widget()->_onRender( pDevice, rc, rc, clip2 ); rc.x += m_pColumns[i].m_realWidth - m_cellPadding.left; // Left cellpadding already added... } } r.y += pRow->Height() + m_cellPadding.Height(); pRow = (WgTableRow *) pRow->Next(); iRowColor++; } // Possibly fill with empty rows if( m_emptyRowHeight != 0 && pRow == 0 ) { while( r.y <= clipView.y + clipView.h ) { r.h = m_emptyRowHeight; WgRect u; if( u.Intersection( r, clipView ) ) { if( m_nRowColors > 0 ) { WgColor color = m_pRowColors[ iRowColor % m_nRowColors ]; if( 0 != color.a ) pDevice->Fill( u, color ); } if( m_nRowBlocks > 0 ) { WgBlocksetPtr p = m_pRowBlocks[ iRowColor % m_nRowBlocks ]; if( p ) pDevice->ClipBlitBlock(u, p->GetBlock(WG_MODE_NORMAL), r ); } } r.y += r.h; iRowColor++; } } }