WgRect WgPackList::_headerGeo() const { if( m_bHorizontal ) return WgRect( _windowSection().x, 0, m_header.m_width, m_size.h ); else return WgRect( 0, _windowSection().y, m_size.w, m_header.m_height ); }
void WgPanel::_onMaskPatches( WgPatches& patches, const WgRect& geo, const WgRect& clip, WgBlendMode blendMode ) { //TODO: Don't just check IsOpaque() globally, check rect by rect. if( (m_bOpaque && blendMode == WG_BLENDMODE_BLEND) || blendMode == WG_BLENDMODE_OPAQUE ) { patches.Sub( WgRect(geo,clip) ); return; } switch( m_maskOp ) { case WG_MASKOP_RECURSE: { WgRect childGeo; WgPanelHook * p = static_cast<WgPanelHook*>(_firstHookWithGeo( childGeo )); while(p) { if( p->IsVisible() ) p->_widget()->_onMaskPatches( patches, childGeo + geo.Pos(), clip, blendMode ); p = static_cast<WgPanelHook*>(_nextHookWithGeo( childGeo, p )); } break; } case WG_MASKOP_SKIP: break; case WG_MASKOP_MASK: patches.Sub( WgRect(geo,clip) ); break; } }
WgRect WgPackList::_listCanvas() const { if( m_bHorizontal ) return WgRect(m_header.m_width, 0, m_size.w - m_header.m_width, m_size.h ); else return WgRect(0, m_header.m_height, m_size.w, m_size.h - m_header.m_height); // List canvas in widgets own coordinate system. }
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 ); }
WgRect WgTablePanel::GetCellGeo( int row, int column ) { if( column >= m_nColumns ) return WgRect(); // Invalid column; WgRect r( 0, 0, 0, 0 ); // Adjust for header if( m_bShowHeader && m_pHeaderGfx ) r.y += m_pHeaderGfx->Height(); WgTableRow * pRow = m_rows.First(); // Forward to our row for( int i = 0 ; i < row ; i++ ) { if( !pRow ) return WgRect(); // Invalid row. if( pRow->IsVisible() ) r.y += pRow->Height() + m_cellPadding.Height(); pRow = pRow->Next(); } r.y += m_cellPadding.top; // Set cell height if( pRow->IsVisible() ) r.h = pRow->Height(); else r.h = 0; // Go through columns, determine x-pos. for( int i = 0 ; i < column ; i++ ) { if( m_pColumns[i].m_bVisible ) r.x += m_pColumns[i].m_realWidth; } // Determine width r.w = m_pColumns[column].m_realWidth; if( column == m_nColumns-1 && r.x + r.w < m_widgetSize.w ) r.w = m_widgetSize.w - r.x; // Last column stretches to end of tableview... // Apply padding r.x += m_cellPadding.left; r.w -= m_cellPadding.Width(); if( r.w < 0 ) r.w = 0; return r; }
void WgPopupLayer::_onRequestRender( const WgRect& rect, const WgPopupHook * pHook ) { // Clip our geometry and put it in a dirtyrect-list WgPatches patches; patches.Add( WgRect( rect, WgRect(0,0,m_size)) ); // Remove portions of dirty rect that are covered by opaque upper siblings, // possibly filling list with many small dirty rects instead. WgPopupHook * pCover; if( pHook ) pCover = pHook->_next(); else pCover = m_popupHooks.First(); while( pCover ) { if( pCover->m_geo.IntersectsWith( rect ) ) pCover->_widget()->_onMaskPatches( patches, pCover->m_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::_onMaskPatches( WgPatches& patches, const WgRect& geo, const WgRect& clip, WgBlendMode blendMode ) { if( (m_bOpaque && blendMode == WG_BLENDMODE_BLEND) || blendMode == WG_BLENDMODE_OPAQUE) patches.Sub( WgRect(geo,clip) ); else if( m_bOpaqueEntries && blendMode == WG_BLENDMODE_BLEND ) { if( m_bHorizontal ) patches.Sub( WgRect( WgRect( geo.x, geo.y, WgMin(geo.w,m_contentLength), geo.h ), clip ) ); else patches.Sub( WgRect( WgRect( geo.x, geo.y, geo.w, WgMin(geo.h,m_contentLength) ), clip ) ); } else { WgRect childGeo; WgPackListHook * p = static_cast<WgPackListHook*>(_firstHookWithGeo( childGeo )); while(p) { if( p->_isVisible() ) p->_widget()->_onMaskPatches( patches, childGeo + geo.Pos(), clip, blendMode ); p = static_cast<WgPackListHook*>(_nextHookWithGeo( childGeo, p )); } } }
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 ) ); } }
WgRoot * setupGUI( WgGfxDevice * pDevice ) { WgResDB * pDB = sdl_wglib::LoadStdGizmos( "../resources/blocks.png", WgSurfaceFactorySoft() ); if( !pDB ) return 0; WgRoot * pRoot = new WgRoot( pDevice ); WgGizmoFlexgeo * pMainContainer = new WgGizmoFlexgeo(); int hAnchorLeft = pMainContainer->AddAnchor( 0.f, 0.f, WgCoord(0,100) ); int hAnchorRight = pMainContainer->AddAnchor( 1.f, 0.f, WgCoord(0,100) ); pRoot->SetChild(pMainContainer); WgGizmoStack * pPanelStack = new WgGizmoStack(); pMainContainer->AddChild( pPanelStack, WG_NORTHWEST, hAnchorRight ); // WgGizmo * pCheckeredBack = pDB->CloneGizmo( "bg_blue_gradient" ); WgGizmo * pCheckeredBack = pDB->CloneGizmo( "bg_checkered_grey" ); pMainContainer->AddChild( pCheckeredBack, hAnchorLeft, WG_SOUTHEAST ); WgGizmo * pPanelBack = pDB->CloneGizmo( "plate" ); pPanelStack->AddChild( pPanelBack ); WgGizmoFill * pFill = new WgGizmoFill(); pFill->SetColor( WgColor(255,0,0) ); pMainContainer->AddChild( pFill, WgRect(100,100,100,100) ); WgGizmoFill * pFill2 = new WgGizmoFill(); pFill2->SetColor( WgColor(0,255,0) ); pMainContainer->AddChild( pFill2, WgRect(200,100,100,100) ); WgGizmoFill * pFill3 = new WgGizmoFill(); pFill3->SetColor( WgColor(0,0,255) ); pMainContainer->AddChild( pFill3, WgRect(300,100,100,100) ); WgGizmoText * pText = new WgGizmoText(); pText->SetTextProperties( WgBase::GetDefaultTextprop() ); pText->SetText( "TESTING" ); pPanelStack->AddChild( pText ); WgGizmo * pSlider = pDB->CloneGizmo( "hslider" ); WgStackHook * pSliderHook = pPanelStack->AddChild( pSlider ); // pSliderHook->SetOrientation( WG_SOUTH ); pSliderHook->SetBorder( WgBorder(0,0,81,0) ); // return pRoot; }
void WgPackList::_onCollectPatches( WgPatches& container, const WgRect& geo, const WgRect& clip ) { if( m_pSkin ) container.Add( WgRect( geo, clip ) ); else { if( m_bHorizontal ) container.Add( WgRect( WgRect( geo.x, geo.y, WgMin(geo.w,m_contentLength), geo.h ), clip ) ); else container.Add( WgRect( WgRect( geo.x, geo.y, geo.w, WgMin(geo.h,m_contentLength) ), clip ) ); } }
WgRect WgCaret2::DirtyRect( WgCoord pos ) const { switch( m_mode ) { case WG_CARET_INSERT: return WgRect( pos.x, pos.y - m_glyphAscend, WgMax(1, m_glyphSize/8), m_glyphAscend + m_glyphDescend ); case WG_CARET_OVERWRITE: return WgRect( pos.x, pos.y - m_glyphAscend, m_glyphAdvance, m_glyphAscend + m_glyphDescend ); case WG_CARET_EOL: return WgRect( pos.x, pos.y - m_glyphAscend, WgMax(1, m_glyphSize/8), m_glyphAscend + m_glyphDescend ); } }
void WgMenu::_onMaskPatches( WgPatches& patches, const WgRect& geo, const WgRect& clip, WgBlendMode blendMode ) { if( (m_bOpaque && blendMode == WG_BLENDMODE_BLEND) || blendMode == WG_BLENDMODE_OPAQUE ) { patches.Sub( WgRect( geo, clip ) ); } else if( blendMode == WG_BLENDMODE_BLEND && m_pSkin ) { if( m_pSkin->IsOpaque() ) patches.Sub( WgRect( geo, clip ) ); else if( m_pSkin->IsOpaque() ) patches.Sub( WgRect( geo, clip ) ); } }
void WgSimpleVolumeMeter::_renderHold( WgGfxDevice * pDevice, int nb, const WgRect& _rect, const WgRect& _clip ) { if( m_holdHeight == 0.f ) return; // Hold should not be displayed. int height = (int) (m_holdHeight * _rect.h); if( height < 1 ) height = 1; WgColor c; int ofs = (int) ((1.f - m_hold[nb]) * _rect.h); if( ofs < m_sectionPixelHeight[2] ) { c = m_sectionColors[2]; if( ofs + height > m_sectionPixelHeight[2] ) ofs = m_sectionPixelHeight[2] - height; } else if( ofs < m_sectionPixelHeight[2] + m_sectionPixelHeight[1] ) { c = m_sectionColors[1]; if( ofs + height > m_sectionPixelHeight[2] + m_sectionPixelHeight[1] ) ofs = m_sectionPixelHeight[2] + m_sectionPixelHeight[1] - height; } else { c = m_sectionColors[0]; } WgRect r( _rect.x, _rect.y + ofs, _rect.w, height ); pDevice->Fill( WgRect( r, _clip ), c ); }
WgTab * WgTablist::_pos2Tab( int x, int y ) const { if( x < 0 || y < 0 ) return 0; bool bMovingUp = true; WgTab * pHit = NULL; WgTab * pTab = m_tabs.First(); WgSize sz = Size(); while( pTab ) { if(pTab->m_bVisible) { // if(pTab == m_pTabSelected) // bMovingUp = false; WgSkinPtr pSrc = _tabSkin(pTab); bool bHit = false; // Tab is hit if position is on a non-transparent (alpha != 0) pixel of the block // or inside tabs text-area. WgRect tabCanvas = WgRect(0,0,pTab->m_width,sz.h); WgRect tabContent; if( pSrc ) tabContent = pSrc->ContentRect( tabCanvas, _tabState(*pTab) ); else tabContent = tabCanvas; if( m_bTabOpaqueForMouse && tabCanvas.Contains(x,y) ) bHit = true; else if( tabContent.Contains( WgCoord(x,y) ) ) bHit = true; else if( pSrc ) bHit = pSrc->MarkTest( WgCoord(x,y), tabCanvas, _tabState(*pTab), m_markOpacity ); if( bHit ) { /* // Handle overlap if(bMovingUp) pHit = pTab; else return pTab; */ if( pTab == m_pTabSelected ) return pTab; else pHit = pTab; } x -= pTab->m_advance; } pTab = pTab->Next(); } return pHit; }
WgRect WgStackHook::_getGeo( const WgRect& parentGeo ) const { WgRect base = parentGeo - m_padding; if( base.w <= 0 || base.h <= 0 ) return WgRect(0,0,0,0); switch( m_sizePolicy ) { default: case DEFAULT: { WgSize size = m_pWidget->PreferredSize(); WgRect geo = WgUtil::OrigoToRect( m_origo, base, size ); if( geo.w > base.w ) { geo.x = 0; geo.w = base.w; } if( geo.h > base.h ) { geo.y = 0; geo.h = base.h; } return geo; } case STRETCH: { return base; } case SCALE: { WgSize orgSize = m_pWidget->PreferredSize(); WgSize size; float fracX = orgSize.w / (float) base.w; float fracY = orgSize.h / (float) base.h; if( fracX > fracY ) { size.w = base.w; size.h = int (orgSize.h / fracX); } else { size.h = base.h; size.w = (int) (orgSize.w / fracY); } return WgUtil::OrigoToRect( m_origo, base, size ); } } }
void WgImage::SetImage( const WgSurfacePtr& pSurface, const WgRect& rect ) { if( pSurface != m_pSurface || rect != m_rect ) { bool bResize = false; if( rect.w != m_rect.w || rect.h != m_rect.h ) bResize = true; m_pSurface = pSurface; if( pSurface ) m_rect = WgRect( rect, WgRect(pSurface->Size()) ); else m_rect.Clear(); if( bResize ) _requestResize(); _requestRender(); } }
WgRect WgMenu::_scrollbarGeo( const WgRect& menuGeo ) const { if( m_scrollbarHook._widget() ) { WgRect contentGeo = menuGeo - _getPadding(); WgRect scrollbarGeo( contentGeo.x + contentGeo.w - m_scrollbarHook.m_size.w, contentGeo.y, m_scrollbarHook.m_size.w, contentGeo.h ); //TODO: Scrollbar is now hardcoded to right side. return scrollbarGeo; } else return WgRect(); }
void WgCaret2::Render( WgGfxDevice * pDevice, WgCoord pos, const WgRect& clip ) { if( m_ticks < m_cycleLength / 2 ) { WgRect r = DirtyRect(pos); WgBlendMode oldMode = pDevice->GetBlendMode(); pDevice->SetBlendMode(WG_BLENDMODE_INVERT); pDevice->Fill( WgRect(r,clip), WgColor::black ); pDevice->SetBlendMode(oldMode); } }
WgBorder WgMenu::_getPadding() const { //TODO: This is ugly and doesn't take ContentShift of various states into account. if( m_pSkin ) { WgRect r = m_pSkin->ContentRect( WgRect(0,0,1000,1000), WG_STATE_NORMAL ); return WgBorder(r.x, r.y, 1000-r.w, 1000-r.h); } else return WgBorder(0); }
WgBorder WgMenubar::_getEntryBorder() const { //TODO: This doesn't take ContentShift for different states into account. if( m_pEntrySkin ) { WgRect r = m_pEntrySkin->ContentRect( WgRect(0,0,1000,1000), WG_STATE_NORMAL ); return WgBorder(r.x,r.y,1000-r.w,1000-r.h); } else return WgBorder(10,0,10,0); // 10 pixels on each side as default margin. Should do something more intelligent here, like taking fonts avgSpacing into account... }
void * WgSDLSurface::Lock( WgAccessMode mode ) { if( m_accessMode != WG_NO_ACCESS || mode == WG_NO_ACCESS ) return 0; SDL_LockSurface(m_pSurface); m_accessMode = WG_READ_WRITE; m_pPixels = (Uint8*) m_pSurface->pixels; m_lockRegion = WgRect( 0, 0, m_pSurface->w, m_pSurface->h ); return m_pSurface->pixels; }
WgRect WgTableHook::Geo() const { WgTablePanel * pTable = Row()->Table(); if( pTable ) { int row = pTable->GetRowNb( Row() ); int column = ColumnNb(); return pTable->GetCellGeo( row, column ); } else return WgRect(); }
void WgGfxDevice::ClipBlitHorrBar( const WgRect& _clip, const WgSurfacePtr& _pSurf, const WgRect& _src, const WgBorder& _borders, bool _bTile, int _dx, int _dy, int _len ) { /* This can be optimized by handling clipping directly instead of calling clipBlit(). */ // Blit left edge WgRect r( _src.x, _src.y, _borders.left, _src.h ); ClipBlit( _clip, _pSurf, r, _dx, _dy ); _len -= _borders.Width(); // Remove left and right edges from len. _dx += _borders.left; // Blit tiling part r.x += _borders.left; r.w = _src.w - _borders.Width(); if( _bTile ) { while( _len > r.w ) { ClipBlit( _clip, _pSurf, r, _dx, _dy ); _len -= r.w; _dx += r.w; } if( _len != 0 ) { r.w = _len; ClipBlit( _clip, _pSurf, r, _dx, _dy ); _dx += _len; } } else { ClipStretchBlit( _clip, _pSurf, r, WgRect( _dx, _dy, _len, r.h ) ); _dx += _len; } // Blit right edge r.x = _src.x + _src.w - _borders.right; r.w = _borders.right; ClipBlit( _clip, _pSurf, r, _dx, _dy ); }
void WgGfxDevice::ClipBlitVertBar( const WgRect& _clip, const WgSurfacePtr& _pSurf, const WgRect& _src, const WgBorder& _borders, bool _bTile, int _dx, int _dy, int _len ) { /* This can be optimized by handling clipping directly instead of calling clipBlit(). */ // Blit top edge WgRect r( _src.x, _src.y, _src.w, _borders.top ); ClipBlit( _clip, _pSurf, r, _dx, _dy ); _len -= _borders.Height(); // Remove top and bottom edges from len. _dy += _borders.top; // Blit tiling part r.y += _borders.top; r.h = _src.h - _borders.Height(); if( _bTile ) { while( _len > r.h ) { ClipBlit( _clip, _pSurf, r, _dx, _dy ); _len -= r.h; _dy += r.h; } if( _len != 0 ) { r.h = _len; ClipBlit( _clip, _pSurf, r, _dx, _dy ); _dy += _len; } } else { ClipStretchBlit( _clip, _pSurf, r, WgRect( _dx, _dy, r.w, _len ) ); _dy += _len; } // Blit bottom edge r.y = _src.y + _src.h - _borders.bottom; r.h = _borders.bottom; ClipBlit( _clip, _pSurf, r, _dx, _dy ); }
void WgGfxDevice::BlitHorrBar( const WgSurfacePtr& _pSurf, const WgRect& _src, const WgBorder& _borders, bool _bTile, int _dx, int _dy, int _len ) { // Blit left edge WgRect r( _src.x, _src.y, _borders.left, _src.h ); Blit( _pSurf, r, _dx, _dy ); _len -= _borders.Width(); // Remove left and right edges from len. _dx += _borders.left; // Blit tiling part r.x += _borders.left; r.w = _src.w - _borders.Width(); if( _bTile ) { while( _len > r.w ) { Blit( _pSurf, r, _dx, _dy ); _len -= r.w; _dx += r.w; } if( _len != 0 ) { r.w = _len; Blit( _pSurf, r, _dx, _dy ); _dx += _len; } } else { StretchBlit( _pSurf, r, WgRect( _dx, _dy, _len, r.h ) ); _dx += _len; } // Blit right edge r.x = _src.x + _src.w - _borders.right; r.w = _borders.right; Blit( _pSurf, r, _dx, _dy ); }
void WgGfxDevice::BlitVertBar( const WgSurfacePtr& _pSurf, const WgRect& _src, const WgBorder& _borders, bool _bTile, int _dx, int _dy, int _len ) { // Blit top edge WgRect r( _src.x, _src.y, _src.w, _borders.top ); Blit( _pSurf, r, _dx, _dy ); _len -= _borders.Height(); // Remove top and bottom borders from len. _dy += _borders.top; // Blit tiling part r.y += _borders.top; r.h = _src.h - _borders.Height(); if( _bTile ) { while( _len > r.h ) { Blit( _pSurf, r, _dx, _dy ); _len -= r.h; _dy += r.h; } if( _len != 0 ) { r.h = _len; Blit( _pSurf, r, _dx, _dy ); _dy += _len; } } else { StretchBlit( _pSurf, r, WgRect( _dx, _dy, r.w, _len ) ); _dy += _len; } // Blit bottom edge r.y = _src.y + _src.h - _borders.bottom; r.h = _borders.bottom; Blit( _pSurf, r, _dx, _dy ); }
void WgSimpleVolumeMeter::_renderPeak( WgGfxDevice * pDevice, int nb, const WgRect& _rect, const WgRect& _clip ) { int height = (int) (m_peak[nb] * _rect.h); int ofs = 0; for( int i = 0 ; i < 3 ; i++ ) { if( height <= 0 ) break; int sectionHeight = m_sectionPixelHeight[i]; if( sectionHeight > height ) sectionHeight = height; WgRect r( _rect.x, _rect.y + _rect.h - ofs - sectionHeight, _rect.w, sectionHeight ); pDevice->Fill( WgRect( r, _clip ), m_sectionColors[i] ); ofs += sectionHeight; height -= sectionHeight; } }
void WgStackPanel::_onRenderRequested( WgVectorHook * _pHook ) { WgStackHook * pHook = static_cast<WgStackHook*>(_pHook); _onRenderRequested(pHook, pHook->_getGeo(WgRect(0,0,m_size))); }
void WgMenu::_onRender( WgGfxDevice * pDevice, const WgRect& canvas, const WgRect& window, const WgRect& clip ) { WgWidget::_onRender(pDevice,canvas,window,clip); // Render the menu-items WgRect contentRect = m_pSkin?m_pSkin->ContentRect(canvas, m_state):canvas; WgRect contentClip( contentRect, clip ); // A clip rectangle for content. WgMenuItem * pItem = m_items.First(); int yPos = contentRect.y - m_contentOfs; int xPosText = contentRect.x + m_iconFieldWidth; int xPosIcon = contentRect.x; int textFieldLen = contentRect.w - m_iconFieldWidth - m_arrowFieldWidth; WgPen entryPen( pDevice, WgCoord( xPosText, yPos ), contentClip ); WgPen accelPen( pDevice, WgCoord( xPosText, yPos ), contentClip ); unsigned int item = 1; while( pItem ) { if( pItem->IsVisible() ) { if( pItem->GetType() == SEPARATOR ) { if( m_pSeparatorSkin ) { WgRect dest( contentRect.x, yPos + m_sepBorder.top, contentRect.w, m_pSeparatorSkin->PreferredSize().h ); m_pSeparatorSkin->Render( pDevice, dest, m_state, contentClip ); yPos += m_sepHeight; } } else { WgState state = WG_STATE_DISABLED; if( ((WgMenuEntry*)pItem)->IsEnabled() ) state = WG_STATE_NORMAL; if( item == m_markedItem ) state = WG_STATE_HOVERED; // Render the tile for this entry WgRect tileDest( contentRect.x, yPos, contentRect.w, m_entryHeight ); // WgRect tileClip( contentClip, tileDest); if( m_pEntrySkin ) m_pEntrySkin->Render( pDevice, tileDest, state, contentClip ); // Print the text (if any) const WgChar * pText = ((WgMenuEntry*)pItem)->GetText().Chars(); if( pText->Glyph() != 0 ) { WgTextAttr attr; WgTextTool::AddPropAttributes( attr, WgBase::GetDefaultTextprop(), state ); // if( m_pSkin ) // WgTextTool::SetAttrColor( attr, m_pSkin->TextColors(), mode ); WgTextTool::AddPropAttributes( attr, m_pEntryProp, state ); entryPen.SetAttributes( attr ); int y = yPos + (m_entryHeight - entryPen.GetLineHeight())/2 + entryPen.GetBaseline(); entryPen.SetPos( WgCoord( xPosText, y ) ); pDevice->PrintLine( entryPen, attr, pText ); } // Print the accel text (if any) const WgChar * pAccelText = ((WgMenuEntry*)pItem)->GetAccelText().Chars(); if( pAccelText->Glyph() != 0 ) { WgTextAttr attr; WgTextTool::AddPropAttributes( attr, WgBase::GetDefaultTextprop(), state ); // if( m_pSkin ) // WgTextTool::SetAttrColor( attr, m_pSkin->TextColors(), mode ); WgTextTool::AddPropAttributes( attr, m_pKeyAccelProp, state ); accelPen.SetAttributes( attr ); int y = yPos + (m_entryHeight - accelPen.GetLineHeight())/2 + accelPen.GetBaseline(); int width = WgTextTool::lineWidth( attr, state, pAccelText ); int x = xPosText + textFieldLen - width; accelPen.SetPos( WgCoord(x, y) ); pDevice->PrintLine( accelPen, attr, pAccelText ); } // Show the icon/checkbox/radiobutton (if any) switch( pItem->GetType() ) { case ENTRY: { WgSkinPtr pIcon = ((WgMenuEntry*)pItem)->GetIcon(); if( pIcon ) { WgSize sz = pIcon->PreferredSize(); if( sz.w > m_iconFieldWidth ) sz.w = m_iconFieldWidth; if( sz.h > m_entryHeight ) sz.h = m_entryHeight; int y = yPos + (m_entryHeight - sz.h)/2; int x = xPosIcon + (m_iconFieldWidth - sz.w)/2; pIcon->Render( pDevice, WgRect(x,y,sz), state, contentClip ); } } break; case CHECKBOX: { WgState checkboxState = state; if( ((WgMenuCheckBox*)pItem)->IsChecked() ) checkboxState.SetSelected(true); if( m_pCheckBoxSkin ) { WgSize sz = m_pCheckBoxSkin->PreferredSize(); int y = yPos + (m_entryHeight - sz.h)/2; int x = xPosIcon + (m_iconFieldWidth - sz.w)/2; m_pCheckBoxSkin->Render( pDevice, WgRect(x,y,sz), checkboxState, contentClip ); } } break; case RADIOBUTTON: { WgState radiobuttonState = state; if( ((WgMenuRadioButton*)pItem)->IsSelected() ) radiobuttonState.SetSelected(true); if( m_pRadioButtonSkin ) { WgSize sz = m_pRadioButtonSkin->PreferredSize(); int y = yPos + (m_entryHeight - sz.h)/2; int x = xPosIcon + (m_iconFieldWidth - sz.w)/2; m_pRadioButtonSkin->Render( pDevice, WgRect(x,y,sz), radiobuttonState, contentClip ); } } break; case SUBMENU: { //TODO: Show submenu arrow. } break; default: break; } yPos += m_entryHeight; } } pItem = pItem->Next(); item++; } }
WgRect WgMenu::ScrollbarHook::GlobalGeo() const { WgRect content = m_pParent->GlobalGeo() - m_pParent->_getPadding(); return WgRect( content.x + content.w - m_size.w, content.y, m_size ); }