diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-05-22 15:13:48 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-05-22 15:35:13 +0100 |
commit | 55d052d2ae94522237206bc5ff260ea4ae037f96 (patch) | |
tree | d6a5014e31ee6245118884b5177b519b9e87368b | |
parent | 15b6db458f5516377703bab8a2860d43753441ed (diff) |
tdf#91366 - invalidate only individual menu items to render highlight.
Change-Id: I0dd741829dd315ed86e3fcf79b7fb4da349d0ac8
-rw-r--r-- | vcl/source/window/menufloatingwindow.cxx | 61 | ||||
-rw-r--r-- | vcl/source/window/menufloatingwindow.hxx | 4 |
2 files changed, 53 insertions, 12 deletions
diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx index 46a997a2ff39..0093ba1949ca 100644 --- a/vcl/source/window/menufloatingwindow.cxx +++ b/vcl/source/window/menufloatingwindow.cxx @@ -80,7 +80,7 @@ void MenuFloatingWindow::doShutdown() { MenuFloatingWindow* pPWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->ImplGetWindow()); if (pPWin) - pPWin->Invalidate(); //pPWin->HighlightItem( i, false ); + pPWin->InvalidateItem(i); } } @@ -136,6 +136,7 @@ void MenuFloatingWindow::ApplySettings(vcl::RenderContext& rRenderContext) rRenderContext.SetLineColor(); } +/// Get a negative pixel offset for an offset menu long MenuFloatingWindow::ImplGetStartY() const { long nY = 0; @@ -183,14 +184,13 @@ void MenuFloatingWindow::ImplHighlightItem( const MouseEvent& rMEvt, bool bMBDow if( ! pMenu ) return; - long nY = nScrollerHeight + ImplGetSVData()->maNWFData.mnMenuFormatBorderY; + long nY = GetInitialItemY(); long nMouseY = rMEvt.GetPosPixel().Y(); Size aOutSz = GetOutputSizePixel(); if ( ( nMouseY >= nY ) && ( nMouseY < ( aOutSz.Height() - nY ) ) ) { bool bHighlighted = false; size_t nCount = pMenu->pItemList->size(); - nY += ImplGetStartY(); // ggf. gescrollt. for ( size_t n = 0; !bHighlighted && ( n < nCount ); n++ ) { if ( pMenu->ImplIsVisible( n ) ) @@ -681,7 +681,7 @@ void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, bool bStartPopupTime if ( nHighlightedItem != ITEMPOS_INVALID ) { - Invalidate(); //HighlightItem( nHighlightedItem, false ); + InvalidateItem(nHighlightedItem); pMenu->ImplCallEventListeners( VCLEVENT_MENU_DEHIGHLIGHT, nHighlightedItem ); } @@ -704,12 +704,12 @@ void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, bool bStartPopupTime MenuFloatingWindow* pPWin = static_cast<MenuFloatingWindow*>(pMenu->pStartedFrom->ImplGetWindow()); if( pPWin && pPWin->nHighlightedItem != i ) { - pPWin->Invalidate(); //HighlightItem( i, true ); + pPWin->InvalidateItem(i); pPWin->nHighlightedItem = i; } } } - Invalidate(); //HighlightItem( nHighlightedItem, true ); + InvalidateItem(nHighlightedItem); pMenu->ImplCallHighlight( nHighlightedItem ); } else @@ -728,15 +728,49 @@ void MenuFloatingWindow::ChangeHighlightItem( sal_uInt16 n, bool bStartPopupTime } } -void MenuFloatingWindow::HighlightItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHighlight) +/// Calculate the initial vertical pixel offset of the first item. +/// May be negative for scrolled windows. +long MenuFloatingWindow::GetInitialItemY(long *pStartY) const +{ + long nStartY = ImplGetStartY(); + if (pStartY) + *pStartY = nStartY; + return nScrollerHeight + nStartY + + ImplGetSVData()->maNWFData.mnMenuFormatBorderY; +} + +/// Emit an Invalidate just for this item's area +void MenuFloatingWindow::InvalidateItem(sal_uInt16 nPos) +{ + if (!pMenu) + return; + + long nY = GetInitialItemY(); + size_t nCount = pMenu->pItemList->size(); + for (size_t n = 0; n < nCount; n++) + { + MenuItemData* pData = pMenu->pItemList->GetDataFromPos( n ); + long nHeight = pData->aSz.Height(); + if (n == nPos) + { + Size aWidth( GetSizePixel() ); + Rectangle aRect(Point(0, nY), Size(aWidth.Width(), nHeight)); + Invalidate( aRect ); + } + nY += nHeight; + } +} + +void MenuFloatingWindow::RenderHighlightItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHighlight) { if (!pMenu) return; Size aSz = rRenderContext.GetOutputSizePixel(); - long nStartY = ImplGetStartY(); - long nY = nScrollerHeight + nStartY + ImplGetSVData()->maNWFData.mnMenuFormatBorderY; + long nX = 0; + long nStartY; + long nY = GetInitialItemY(&nStartY); if (pMenu->pLogo) nX = pMenu->pLogo->aBitmap.GetSizePixel().Width(); @@ -1097,11 +1131,14 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent ) } } -void MenuFloatingWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle&) +void MenuFloatingWindow::Paint(vcl::RenderContext& rRenderContext, const Rectangle &rPaintRect) { if (!pMenu) return; + rRenderContext.Push( PushFlags::CLIPREGION ); + rRenderContext.SetClipRegion(vcl::Region(rPaintRect)); + if (rRenderContext.IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL)) { rRenderContext.SetClipRegion(); @@ -1122,7 +1159,9 @@ void MenuFloatingWindow::Paint(vcl::RenderContext& rRenderContext, const Rectang rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuColor()); pMenu->ImplPaint(rRenderContext, nScrollerHeight, ImplGetStartY()); if (nHighlightedItem != ITEMPOS_INVALID) - HighlightItem(rRenderContext, nHighlightedItem, true); + RenderHighlightItem(rRenderContext, nHighlightedItem, true); + + rRenderContext.Pop(); } void MenuFloatingWindow::ImplDrawScroller(vcl::RenderContext& rRenderContext, bool bUp) diff --git a/vcl/source/window/menufloatingwindow.hxx b/vcl/source/window/menufloatingwindow.hxx index 9336664a5bc9..00c797d6942e 100644 --- a/vcl/source/window/menufloatingwindow.hxx +++ b/vcl/source/window/menufloatingwindow.hxx @@ -78,6 +78,9 @@ protected: void ImplHighlightItem( const MouseEvent& rMEvt, bool bMBDown ); long ImplGetStartY() const; Rectangle ImplGetItemRect( sal_uInt16 nPos ); + void RenderHighlightItem( vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHighlight ); + long GetInitialItemY( long *pOptStartY = NULL ) const; + void InvalidateItem( sal_uInt16 nPos ); public: MenuFloatingWindow(Menu* pMenu, vcl::Window* pParent, WinBits nStyle); @@ -112,7 +115,6 @@ public: PopupMenu* GetActivePopup() const { return pActivePopup; } void KillActivePopup( PopupMenu* pThisOnly = NULL ); - void HighlightItem(vcl::RenderContext& rRenderContext, sal_uInt16 nPos, bool bHighlight); void ChangeHighlightItem(sal_uInt16 n, bool bStartPopupTimer); sal_uInt16 GetHighlightedItem() const { return nHighlightedItem; } |