[Libreoffice-commits] .: 5 commits - svtools/inc svtools/source

Matteo Casalin mcasalin at kemper.freedesktop.org
Sat Mar 3 00:52:32 PST 2012


 svtools/inc/svtools/valueset.hxx    |    8 
 svtools/source/control/valueacc.cxx |   11 -
 svtools/source/control/valueimp.hxx |    6 
 svtools/source/control/valueset.cxx |  312 ++++++++++++++++++++----------------
 4 files changed, 193 insertions(+), 144 deletions(-)

New commits:
commit e336f41e50ea96880dd71a2b42aa37cf53256383
Author: Matteo Casalin <matteo.casalin at gmx.com>
Date:   Tue Feb 28 00:06:24 2012 +0100

    ValueSet: simplified autoscroll logic

diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
index 9db8f93..8cd032b 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -994,46 +994,35 @@ void ValueSet::ImplDraw()
 
 bool ValueSet::ImplScroll( const Point& rPos )
 {
-    Size aOutSize = GetOutputSizePixel();
-    long nScrBarWidth;
-
-    if ( mpScrBar )
-        nScrBarWidth = mpScrBar->GetSizePixel().Width();
-    else
-        nScrBarWidth = 0;
-
-    if ( !mbScroll || (rPos.X() < 0) || (rPos.X() > aOutSize.Width()-nScrBarWidth) )
+    if ( !mbScroll || !maItemListRect.IsInside(rPos) )
         return false;
 
-    long             nScrollOffset;
-    sal_uInt16           nOldLine = mnFirstLine;
-    const Rectangle aTopRect = ImplGetItemRect( mnFirstLine*mnCols );
-    if ( aTopRect.GetHeight() <= 16 )
-        nScrollOffset = SCROLL_OFFSET/2;
-    else
-        nScrollOffset = SCROLL_OFFSET;
-    if ( (mnFirstLine > 0) && (rPos.Y() >= 0) )
+    const long nScrollOffset = (mnItemHeight <= 16) ? SCROLL_OFFSET/2 : SCROLL_OFFSET;
+    bool bScroll = false;
+
+    if ( rPos.Y() <= maItemListRect.Top()+nScrollOffset )
     {
-        long nTopPos = aTopRect.Top();
-        if ( (rPos.Y() >= nTopPos) && (rPos.Y() <= nTopPos+nScrollOffset) )
-            mnFirstLine--;
+        if ( mnFirstLine > 0 )
+        {
+            --mnFirstLine;
+            bScroll = true;
+        }
     }
-    if ( (mnFirstLine == nOldLine) &&
-         (mnFirstLine < (sal_uInt16)(mnLines-mnVisLines)) && (rPos.Y() < aOutSize.Height()) )
+    else if ( rPos.Y() >= maItemListRect.Bottom()-nScrollOffset )
     {
-        const long nBottomPos = ImplGetItemRect((mnFirstLine+mnVisLines-1)*mnCols).Bottom();
-        if ( (rPos.Y() >= nBottomPos-nScrollOffset) && (rPos.Y() <= nBottomPos) )
-            mnFirstLine++;
+        if ( mnFirstLine < static_cast<sal_uInt16>(mnLines-mnVisLines) )
+        {
+            ++mnFirstLine;
+            bScroll = true;
+        }
     }
 
-    if ( mnFirstLine != nOldLine )
-    {
-        mbFormat = true;
-        ImplDraw();
-        return true;
-    }
-    else
+    if ( !bScroll )
         return false;
+
+    mbFormat = true;
+    ImplDraw();
+    return true;
 }
 
 // -----------------------------------------------------------------------
commit 0809906906d7941ceb9ae170a41c482fdd1e6bfa
Author: Matteo Casalin <matteo.casalin at gmx.com>
Date:   Sun Feb 26 22:47:10 2012 +0100

    ValueSet: reduce memory footprint by dynamically evaluating rectangles

diff --git a/svtools/inc/svtools/valueset.hxx b/svtools/inc/svtools/valueset.hxx
index 7e0b7db..22271da 100644
--- a/svtools/inc/svtools/valueset.hxx
+++ b/svtools/inc/svtools/valueset.hxx
@@ -217,6 +217,10 @@ private:
     ValueItemList   mItemList;
     ValueSetItem*   mpNoneItem;
     ScrollBar*      mpScrBar;
+    Rectangle       maNoneItemRect;
+    Rectangle       maItemListRect;
+    long            mnItemWidth;
+    long            mnItemHeight;
     long            mnTextOffset;
     long            mnVisLines;
     long            mnLines;
@@ -241,6 +245,7 @@ private:
     bool            mbScroll : 1;
     bool            mbFullMode : 1;
     bool            mbIsTransientChildrenDisabled : 1;
+    bool            mbHasVisibleItems : 1;
     Color           maColor;
     Link            maDoubleClickHdl;
     Link            maSelectHdl;
@@ -255,7 +260,7 @@ private:
     SVT_DLLPRIVATE void         ImplInitSettings( bool bFont, bool bForeground, bool bBackground );
     SVT_DLLPRIVATE void         ImplInitScrollBar();
     SVT_DLLPRIVATE void         ImplDeleteItems();
-    SVT_DLLPRIVATE void         ImplFormatItem( ValueSetItem* pItem );
+    SVT_DLLPRIVATE void         ImplFormatItem( ValueSetItem* pItem, Rectangle aRect );
     SVT_DLLPRIVATE void         ImplDrawItemText( const XubString& rStr );
     SVT_DLLPRIVATE void         ImplDrawSelect( sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel );
     SVT_DLLPRIVATE void         ImplDrawSelect();
@@ -270,6 +275,7 @@ private:
     SVT_DLLPRIVATE sal_uInt16          ImplGetVisibleItemCount() const;
     SVT_DLLPRIVATE ValueSetItem*    ImplGetVisibleItem( sal_uInt16 nVisiblePos );
     SVT_DLLPRIVATE void         ImplInsertItem( ValueSetItem *const pItem, const size_t nPos );
+    SVT_DLLPRIVATE Rectangle    ImplGetItemRect( size_t nPos ) const;
     SVT_DLLPRIVATE void            ImplFireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue );
     SVT_DLLPRIVATE bool         ImplHasAccessibleListeners();
     SVT_DLLPRIVATE void         ImplTracking( const Point& rPos, bool bRepeat );
diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx
index 7c73a8c..22680c4 100644
--- a/svtools/source/control/valueacc.cxx
+++ b/svtools/source/control/valueacc.cxx
@@ -1108,7 +1108,7 @@ awt::Rectangle SAL_CALL ValueItemAcc::getBounds()
 
     if( mpParent )
     {
-        Rectangle   aRect( mpParent->maRect );
+        Rectangle   aRect( mpParent->mrParent.GetItemRect(mpParent->mnId) );
         Point       aOrigin;
         Rectangle   aParentRect( aOrigin, mpParent->mrParent.GetOutputSizePixel() );
 
@@ -1147,7 +1147,8 @@ awt::Point SAL_CALL ValueItemAcc::getLocationOnScreen()
 
     if( mpParent )
     {
-        const Point aScreenPos( mpParent->mrParent.OutputToAbsoluteScreenPixel( mpParent->maRect.TopLeft() ) );
+        const Point aPos = mpParent->mrParent.GetItemRect(mpParent->mnId).TopLeft();
+        const Point aScreenPos( mpParent->mrParent.OutputToAbsoluteScreenPixel( aPos ) );
 
         aRet.X = aScreenPos.X();
         aRet.Y = aScreenPos.Y();
diff --git a/svtools/source/control/valueimp.hxx b/svtools/source/control/valueimp.hxx
index f7cd13f..0dfd1f0 100644
--- a/svtools/source/control/valueimp.hxx
+++ b/svtools/source/control/valueimp.hxx
@@ -70,13 +70,13 @@ class ValueSet;
 struct ValueSetItem
 {
     ValueSet&           mrParent;
-    sal_uInt16              mnId;
-    ValueSetItemType    meType;
+    sal_uInt16          mnId;
+    sal_uInt8           meType;
+    bool                mbVisible;
     Image               maImage;
     Color               maColor;
     XubString           maText;
     void*               mpData;
-    Rectangle           maRect;
     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >* mpxAcc;
 
     ValueSetItem( ValueSet& rParent );
diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
index 7f77215..9db8f93 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -66,6 +66,8 @@ void ValueSet::ImplInit()
 {
     mpNoneItem          = NULL;
     mpScrBar            = NULL;
+    mnItemWidth         = 0;
+    mnItemHeight        = 0;
     mnTextOffset        = 0;
     mnVisLines          = 0;
     mnLines             = 0;
@@ -89,6 +91,7 @@ void ValueSet::ImplInit()
     mbDoubleSel         = false;
     mbScroll            = false;
     mbFullMode          = true;
+    mbHasVisibleItems   = false;
 
     // #106446#, #106601# force mirroring of virtual device
     maVirDev.EnableRTL( GetParent()->IsRTLEnabled() );
@@ -137,10 +140,12 @@ ValueSet::~ValueSet()
 
 void ValueSet::ImplDeleteItems()
 {
-    for ( size_t i = 0, n = mItemList.size(); i < n; ++i )
+    const size_t n = mItemList.size();
+
+    for ( size_t i = 0; i < n; ++i )
     {
         ValueSetItem *const pItem = mItemList[i];
-        if( !pItem->maRect.IsEmpty() && ImplHasAccessibleListeners() )
+        if ( pItem->mbVisible && ImplHasAccessibleListeners() )
         {
             ::com::sun::star::uno::Any aOldAny, aNewAny;
 
@@ -217,9 +222,8 @@ void ValueSet::ImplInitScrollBar()
 
 // -----------------------------------------------------------------------
 
-void ValueSet::ImplFormatItem( ValueSetItem* pItem )
+void ValueSet::ImplFormatItem( ValueSetItem* pItem, Rectangle aRect )
 {
-    Rectangle aRect = pItem->maRect;
     WinBits nStyle = GetStyle();
     if ( nStyle & WB_ITEMBORDER )
     {
@@ -457,28 +461,26 @@ void ValueSet::Format()
     }
 
     // calculate item size
-    long nColSpace  = (mnCols-1)*mnSpacing;
-    long nLineSpace = ((mnVisLines-1)*mnSpacing)+nNoneSpace;
-    long nItemWidth;
-    long nItemHeight;
+    const long nColSpace  = (mnCols-1)*mnSpacing;
+    const long nLineSpace = ((mnVisLines-1)*mnSpacing)+nNoneSpace;
     if ( mnUserItemWidth && !mnUserCols )
     {
-        nItemWidth = mnUserItemWidth;
-        if ( nItemWidth > aWinSize.Width()-nScrBarWidth-nColSpace )
-            nItemWidth = aWinSize.Width()-nScrBarWidth-nColSpace;
+        mnItemWidth = mnUserItemWidth;
+        if ( mnItemWidth > aWinSize.Width()-nScrBarWidth-nColSpace )
+            mnItemWidth = aWinSize.Width()-nScrBarWidth-nColSpace;
     }
     else
-        nItemWidth = (aWinSize.Width()-nScrBarWidth-nColSpace) / mnCols;
+        mnItemWidth = (aWinSize.Width()-nScrBarWidth-nColSpace) / mnCols;
     if ( mnUserItemHeight && !mnUserVisLines )
     {
-        nItemHeight = mnUserItemHeight;
-        if ( nItemHeight > nCalcHeight-nNoneSpace )
-            nItemHeight = nCalcHeight-nNoneSpace;
+        mnItemHeight = mnUserItemHeight;
+        if ( mnItemHeight > nCalcHeight-nNoneSpace )
+            mnItemHeight = nCalcHeight-nNoneSpace;
     }
     else
     {
         nCalcHeight -= nLineSpace;
-        nItemHeight = nCalcHeight / mnVisLines;
+        mnItemHeight = nCalcHeight / mnVisLines;
     }
 
     // Init VirDev
@@ -487,23 +489,24 @@ void ValueSet::Format()
     maVirDev.SetOutputSizePixel( aWinSize, sal_True );
 
     // nothing is changed in case of too small items
-    long nMinHeight = 2;
-    if ( nStyle & WB_ITEMBORDER )
-        nMinHeight = 4;
-    if ( (nItemWidth <= 0) || (nItemHeight <= nMinHeight) || !nItemCount )
+    if ( (mnItemWidth <= 0) ||
+         (mnItemHeight <= (( nStyle & WB_ITEMBORDER ) ? 4 : 2)) ||
+         !nItemCount )
     {
+        mbHasVisibleItems = false;
+
         if ( nStyle & WB_NONEFIELD )
         {
             if ( mpNoneItem )
             {
-                mpNoneItem->maRect.SetEmpty();
+                mpNoneItem->mbVisible = false;
                 mpNoneItem->maText = GetText();
             }
         }
 
         for ( size_t i = 0; i < nItemCount; i++ )
         {
-            mItemList[i]->maRect.SetEmpty();
+            mItemList[i]->mbVisible = false;
         }
 
         if ( mpScrBar )
@@ -511,6 +514,8 @@ void ValueSet::Format()
     }
     else
     {
+        mbHasVisibleItems = true;
+
         // determine Frame-Style
         if ( nStyle & WB_DOUBLEBORDER )
             mnFrameStyle = FRAME_DRAW_DOUBLEIN;
@@ -532,7 +537,7 @@ void ValueSet::Format()
 
         // draw the selection with double width if the items are bigger
         if ( (nStyle & WB_DOUBLEBORDER) &&
-             ((nItemWidth >= 25) && (nItemHeight >= 20)) )
+             ((mnItemWidth >= 25) && (mnItemHeight >= 20)) )
             mbDoubleSel = true;
         else
             mbDoubleSel = false;
@@ -542,8 +547,8 @@ void ValueSet::Format()
         long nStartY;
         if ( mbFullMode )
         {
-            long nAllItemWidth = (nItemWidth*mnCols)+nColSpace;
-            long nAllItemHeight = (nItemHeight*mnVisLines)+nNoneHeight+nLineSpace;
+            long nAllItemWidth = (mnItemWidth*mnCols)+nColSpace;
+            long nAllItemHeight = (mnItemHeight*mnVisLines)+nNoneHeight+nLineSpace;
             nStartX = (aWinSize.Width()-nScrBarWidth-nAllItemWidth)/2;
             nStartY = (aWinSize.Height()-nAllItemHeight)/2;
         }
@@ -566,12 +571,13 @@ void ValueSet::Format()
 
             mpNoneItem->mnId            = 0;
             mpNoneItem->meType          = VALUESETITEM_NONE;
-            mpNoneItem->maRect.Left()   = x;
-            mpNoneItem->maRect.Top()    = y;
-            mpNoneItem->maRect.Right()  = mpNoneItem->maRect.Left()+aWinSize.Width()-x-1;
-            mpNoneItem->maRect.Bottom() = y+nNoneHeight-1;
+            mpNoneItem->mbVisible       = true;
+            maNoneItemRect.Left()       = x;
+            maNoneItemRect.Top()        = y;
+            maNoneItemRect.Right()      = maNoneItemRect.Left()+aWinSize.Width()-x-1;
+            maNoneItemRect.Bottom()     = y+nNoneHeight-1;
 
-            ImplFormatItem( mpNoneItem );
+            ImplFormatItem( mpNoneItem, maNoneItemRect );
 
             y += nNoneHeight+nNoneSpace;
         }
@@ -580,13 +586,19 @@ void ValueSet::Format()
         sal_uLong nFirstItem = mnFirstLine * mnCols;
         sal_uLong nLastItem = nFirstItem + (mnVisLines * mnCols);
 
+        maItemListRect.Left() = x;
+        maItemListRect.Top() = y;
+        maItemListRect.Right() = x + mnCols*(mnItemWidth+mnSpacing) - mnSpacing - 1;
+        maItemListRect.Bottom() = y + mnVisLines*(mnItemHeight+mnSpacing) - mnSpacing - 1;
+
         if ( !mbFullMode )
         {
             // If want also draw parts of items in the last line,
             // then we add one more line if parts of these line are
             // visible
-            if ( y+(mnVisLines*(nItemHeight+mnSpacing)) < aWinSize.Height() )
+            if ( y+(mnVisLines*(mnItemHeight+mnSpacing)) < aWinSize.Height() )
                 nLastItem += mnCols;
+            maItemListRect.Bottom() = aWinSize.Height() - y;
         }
         for ( size_t i = 0; i < nItemCount; i++ )
         {
@@ -594,14 +606,7 @@ void ValueSet::Format()
 
             if ( (i >= nFirstItem) && (i < nLastItem) )
             {
-                const bool bWasEmpty = pItem->maRect.IsEmpty();
-
-                pItem->maRect.Left()    = x;
-                pItem->maRect.Top()     = y;
-                pItem->maRect.Right()   = pItem->maRect.Left()+nItemWidth-1;
-                pItem->maRect.Bottom()  = pItem->maRect.Top()+nItemHeight-1;
-
-                if( bWasEmpty && ImplHasAccessibleListeners() )
+                if( !pItem->mbVisible && ImplHasAccessibleListeners() )
                 {
                     ::com::sun::star::uno::Any aOldAny, aNewAny;
 
@@ -609,19 +614,20 @@ void ValueSet::Format()
                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
                 }
 
-                ImplFormatItem( pItem );
+                pItem->mbVisible = true;
+                ImplFormatItem( pItem, Rectangle( Point(x,y), Size(mnItemWidth, mnItemHeight) ) );
 
                 if ( !((i+1) % mnCols) )
                 {
                     x = nStartX;
-                    y += nItemHeight+mnSpacing;
+                    y += mnItemHeight+mnSpacing;
                 }
                 else
-                    x += nItemWidth+mnSpacing;
+                    x += mnItemWidth+mnSpacing;
             }
             else
             {
-                if( !pItem->maRect.IsEmpty() && ImplHasAccessibleListeners() )
+                if( pItem->mbVisible && ImplHasAccessibleListeners() )
                 {
                     ::com::sun::star::uno::Any aOldAny, aNewAny;
 
@@ -629,7 +635,7 @@ void ValueSet::Format()
                     ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::CHILD, aOldAny, aNewAny );
                 }
 
-                pItem->maRect.SetEmpty();
+                pItem->mbVisible = false;
             }
         }
 
@@ -642,7 +648,7 @@ void ValueSet::Format()
             if ( nStyle & WB_NONEFIELD )
             {
                 aPos.Y() = nStartY+nNoneHeight+1;
-                aSize.Height() = ((nItemHeight+mnSpacing)*mnVisLines)-2-mnSpacing;
+                aSize.Height() = ((mnItemHeight+mnSpacing)*mnVisLines)-2-mnSpacing;
             }
             mpScrBar->SetPosSizePixel( aPos, aSize );
             mpScrBar->SetRangeMax( mnLines );
@@ -720,24 +726,31 @@ void ValueSet::ImplDrawSelect()
 void ValueSet::ImplDrawSelect( sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel )
 {
     ValueSetItem* pItem;
+    Rectangle aRect;
     if ( nItemId )
     {
-        pItem = mItemList[ GetItemPos( nItemId ) ];
+        const size_t nPos = GetItemPos( nItemId );
+        pItem = mItemList[ nPos ];
+        aRect = ImplGetItemRect( nPos );
     }
     else if ( mpNoneItem )
     {
         pItem = mpNoneItem;
+        aRect = maNoneItemRect;
+    }
+    else if ( bFocus && (pItem = ImplGetFirstItem()) )
+    {
+        aRect = ImplGetItemRect( 0 );
     }
-    else if ( !bFocus || !(pItem = ImplGetFirstItem()) )
+    else
     {
         return;
     }
 
-    if ( !pItem->maRect.IsEmpty() )
+    if ( pItem->mbVisible )
     {
         // draw selection
         const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
-        Rectangle               aRect = pItem->maRect;
         Control::SetFillColor();
 
         Color aDoubleColor( rStyleSettings.GetHighlightColor() );
@@ -875,22 +888,28 @@ void ValueSet::ImplHideSelect( sal_uInt16 nItemId )
 {
     Rectangle aRect;
 
-    size_t nItemPos = GetItemPos( nItemId );
+    const size_t nItemPos = GetItemPos( nItemId );
     if ( nItemPos != VALUESET_ITEM_NOTFOUND )
-        aRect = mItemList[nItemPos]->maRect;
-    else
     {
-        if ( mpNoneItem )
-            aRect = mpNoneItem->maRect;
+        if ( !mItemList[nItemPos]->mbVisible )
+        {
+            return;
+        }
+        aRect = ImplGetItemRect(nItemPos);
     }
-
-    if ( !aRect.IsEmpty() )
+    else
     {
-        HideFocus();
-        Point aPos  = aRect.TopLeft();
-        Size  aSize = aRect.GetSize();
-        DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
+        if ( !mpNoneItem )
+        {
+            return;
+        }
+        aRect = maNoneItemRect;
     }
+
+    HideFocus();
+    const Point aPos  = aRect.TopLeft();
+    const Size  aSize = aRect.GetSize();
+    DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
 }
 
 // -----------------------------------------------------------------------
@@ -988,21 +1007,21 @@ bool ValueSet::ImplScroll( const Point& rPos )
 
     long             nScrollOffset;
     sal_uInt16           nOldLine = mnFirstLine;
-    const Rectangle& rTopRect = mItemList[ mnFirstLine*mnCols ]->maRect;
-    if ( rTopRect.GetHeight() <= 16 )
+    const Rectangle aTopRect = ImplGetItemRect( mnFirstLine*mnCols );
+    if ( aTopRect.GetHeight() <= 16 )
         nScrollOffset = SCROLL_OFFSET/2;
     else
         nScrollOffset = SCROLL_OFFSET;
     if ( (mnFirstLine > 0) && (rPos.Y() >= 0) )
     {
-        long nTopPos = rTopRect.Top();
+        long nTopPos = aTopRect.Top();
         if ( (rPos.Y() >= nTopPos) && (rPos.Y() <= nTopPos+nScrollOffset) )
             mnFirstLine--;
     }
     if ( (mnFirstLine == nOldLine) &&
          (mnFirstLine < (sal_uInt16)(mnLines-mnVisLines)) && (rPos.Y() < aOutSize.Height()) )
     {
-        const long nBottomPos = mItemList[ (mnFirstLine+mnVisLines-1)*mnCols ]->maRect.Bottom();
+        const long nBottomPos = ImplGetItemRect((mnFirstLine+mnVisLines-1)*mnCols).Bottom();
         if ( (rPos.Y() >= nBottomPos-nScrollOffset) && (rPos.Y() <= nBottomPos) )
             mnFirstLine++;
     }
@@ -1021,23 +1040,34 @@ bool ValueSet::ImplScroll( const Point& rPos )
 
 size_t ValueSet::ImplGetItem( const Point& rPos, bool bMove ) const
 {
-    if ( mpNoneItem && mpNoneItem->maRect.IsInside( rPos ) )
+    if ( !mbHasVisibleItems )
     {
-        return VALUESET_ITEM_NONEITEM;
+        return VALUESET_ITEM_NOTFOUND;
     }
 
-    const Rectangle aWinRect( Point(), maVirDev.GetOutputSizePixel() );
+    if ( mpNoneItem && maNoneItemRect.IsInside( rPos ) )
+    {
+        return VALUESET_ITEM_NONEITEM;
+    }
 
-    if ( aWinRect.IsInside( rPos ) )
+    if ( maItemListRect.IsInside( rPos ) )
     {
-        // The point is inside the ValueSet window,
+        const int xc = rPos.X()-maItemListRect.Left();
+        const int yc = rPos.Y()-maItemListRect.Top();
+        // The point is inside the area of item list,
         // let's find the containing item.
-        const size_t nItemCount = mItemList.size();
-        for ( size_t i = 0; i < nItemCount; ++i )
+        const int col = xc/(mnItemWidth+mnSpacing);
+        const int x = xc%(mnItemWidth+mnSpacing);
+        const int row = yc/(mnItemHeight+mnSpacing);
+        const int y = yc%(mnItemHeight+mnSpacing);
+
+        if (x<mnItemWidth && y<mnItemHeight)
         {
-            if ( mItemList[i]->maRect.IsInside( rPos ) )
+            // the point is inside item rect and not inside spacing
+            const size_t item = (mnFirstLine+row)*mnCols+col;
+            if (item < mItemList.size())
             {
-                return i;
+                return item;
             }
         }
 
@@ -1074,10 +1104,11 @@ ValueSetItem* ValueSet::ImplGetFirstItem()
 sal_uInt16 ValueSet::ImplGetVisibleItemCount() const
 {
     sal_uInt16 nRet = 0;
+    const size_t nItemCount = mItemList.size();
 
-    for( size_t n = 0, nItemCount = mItemList.size(); n < nItemCount; ++n )
+    for ( size_t n = 0; n < nItemCount; ++n )
     {
-        if( !mItemList[n]->maRect.IsEmpty() )
+        if ( mItemList[n]->mbVisible )
             ++nRet;
     }
 
@@ -1088,18 +1119,17 @@ sal_uInt16 ValueSet::ImplGetVisibleItemCount() const
 
 ValueSetItem* ValueSet::ImplGetVisibleItem( sal_uInt16 nVisiblePos )
 {
-    ValueSetItem*   pRet = NULL;
-    sal_uInt16          nFoundPos = 0;
+    const size_t nItemCount = mItemList.size();
 
-    for( sal_Int32 n = 0, nItemCount = mItemList.size(); ( n < nItemCount ) && !pRet; n++  )
+    for ( size_t n = 0; n < nItemCount; ++n )
     {
-        ValueSetItem* pItem = mItemList[n];
+        ValueSetItem *const pItem = mItemList[n];
 
-        if( !pItem->maRect.IsEmpty() && ( nVisiblePos == nFoundPos++ ) )
-            pRet = pItem;
+        if ( pItem->mbVisible && !nVisiblePos-- )
+            return pItem;
     }
 
-    return pRet;
+    return NULL;
 }
 
 // -----------------------------------------------------------------------
@@ -1554,15 +1584,14 @@ void ValueSet::RequestHelp( const HelpEvent& rHEvt )
         size_t nItemPos = ImplGetItem( aPos );
         if ( nItemPos != VALUESET_ITEM_NOTFOUND )
         {
-            ValueSetItem* pItem = ImplGetItem( nItemPos );
-            Rectangle aItemRect = pItem->maRect;
+            Rectangle aItemRect = ImplGetItemRect( nItemPos );
             Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
             aItemRect.Left()   = aPt.X();
             aItemRect.Top()    = aPt.Y();
             aPt = OutputToScreenPixel( aItemRect.BottomRight() );
             aItemRect.Right()  = aPt.X();
             aItemRect.Bottom() = aPt.Y();
-            Help::ShowQuickHelp( this, aItemRect, GetItemText( pItem->mnId ) );
+            Help::ShowQuickHelp( this, aItemRect, GetItemText( ImplGetItem( nItemPos )->mnId ) );
             return;
         }
     }
@@ -1590,8 +1619,8 @@ void ValueSet::StateChanged( StateChangedType nType )
     {
         if ( mpNoneItem && !mbFormat && IsReallyVisible() && IsUpdateMode() )
         {
-            ImplFormatItem( mpNoneItem );
-            Invalidate( mpNoneItem->maRect );
+            ImplFormatItem( mpNoneItem, maNoneItemRect );
+            Invalidate( maNoneItemRect );
         }
     }
     else if ( (nType == STATE_CHANGE_ZOOM) ||
@@ -1737,6 +1766,31 @@ void ValueSet::ImplInsertItem( ValueSetItem *const pItem, const size_t nPos )
 
 // -----------------------------------------------------------------------
 
+Rectangle ValueSet::ImplGetItemRect( size_t nPos ) const
+{
+    const size_t nVisibleBegin = static_cast<size_t>(mnFirstLine)*mnCols;
+    const size_t nMaxVisible = static_cast<size_t>(mnVisLines)*mnCols;
+    size_t nVisibleEnd = nVisibleBegin+nMaxVisible;
+    if ( nVisibleEnd>mItemList.size() )
+    {
+        nVisibleEnd = mItemList.size();
+    }
+
+    if ( nPos<nVisibleBegin || nPos>=nVisibleEnd )
+        return Rectangle();
+
+    nPos -= nVisibleBegin;
+
+    const size_t row = nPos/mnCols;
+    const size_t col = nPos%mnCols;
+    const long x = maItemListRect.Left()+col*(mnItemWidth+mnSpacing);
+    const long y = maItemListRect.Top()+row*(mnItemHeight+mnSpacing);
+
+    return Rectangle( Point(x, y), Size(mnItemWidth, mnItemHeight) );
+}
+
+// -----------------------------------------------------------------------
+
 void ValueSet::RemoveItem( sal_uInt16 nItemId )
 {
     size_t nPos = GetItemPos( nItemId );
@@ -1824,12 +1878,12 @@ sal_uInt16 ValueSet::GetItemId( const Point& rPos ) const
 
 Rectangle ValueSet::GetItemRect( sal_uInt16 nItemId ) const
 {
-    size_t nPos = GetItemPos( nItemId );
+    const size_t nPos = GetItemPos( nItemId );
 
-    if ( nPos != VALUESET_ITEM_NOTFOUND )
-        return mItemList[nPos]->maRect;
-    else
-        return Rectangle();
+    if ( nPos!=VALUESET_ITEM_NOTFOUND && mItemList[nPos]->mbVisible )
+        return ImplGetItemRect( nPos );
+
+    return Rectangle();
 }
 
 // -----------------------------------------------------------------------
@@ -2039,8 +2093,9 @@ void ValueSet::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
 
     if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
     {
-        ImplFormatItem( pItem );
-        Invalidate( pItem->maRect );
+        const Rectangle aRect = ImplGetItemRect(nPos);
+        ImplFormatItem( pItem, aRect );
+        Invalidate( aRect );
     }
     else
         mbFormat = true;
@@ -2073,8 +2128,9 @@ void ValueSet::SetItemColor( sal_uInt16 nItemId, const Color& rColor )
 
     if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
     {
-        ImplFormatItem( pItem );
-        Invalidate( pItem->maRect );
+        const Rectangle aRect = ImplGetItemRect(nPos);
+        ImplFormatItem( pItem, aRect );
+        Invalidate( aRect );
     }
     else
         mbFormat = true;
@@ -2108,8 +2164,9 @@ void ValueSet::SetItemData( sal_uInt16 nItemId, void* pData )
     {
         if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
         {
-            ImplFormatItem( pItem );
-            Invalidate( pItem->maRect );
+            const Rectangle aRect = ImplGetItemRect(nPos);
+            ImplFormatItem( pItem, aRect );
+            Invalidate( aRect );
         }
         else
             mbFormat = true;
commit 8d4ab7fd776f8709dab9786951a560c9c59c3ba7
Author: Matteo Casalin <matteo.casalin at gmx.com>
Date:   Sun Feb 19 23:17:51 2012 +0100

    ValueSet: remove redundant check

diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx
index f4405f8..7c73a8c 100644
--- a/svtools/source/control/valueacc.cxx
+++ b/svtools/source/control/valueacc.cxx
@@ -443,9 +443,7 @@ uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessible
         if( VALUESET_ITEM_NONEITEM != nItemPos )
         {
             ValueSetItem *const pItem = mpParent->mItemList[nItemPos];
-
-            if( !pItem->maRect.IsEmpty() )
-               xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
+            xRet = pItem->GetAccessible( mbIsTransientChildrenDisabled );
         }
     }
 
commit 1cc064f1a414446791903bb84c9f166cd3185e14
Author: Matteo Casalin <matteo.casalin at gmx.com>
Date:   Sun Feb 19 18:02:12 2012 +0100

    ValueSet: fix safety check - failure value of GetItemId is 0, not -1

diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx
index 61aec1a..f4405f8 100644
--- a/svtools/source/control/valueacc.cxx
+++ b/svtools/source/control/valueacc.cxx
@@ -436,7 +436,7 @@ uno::Reference< accessibility::XAccessible > SAL_CALL ValueSetAcc::getAccessible
     const sal_uInt16                                    nItemId = mpParent->GetItemId( Point( aPoint.X, aPoint.Y ) );
     uno::Reference< accessibility::XAccessible >    xRet;
 
-    if( ((sal_uInt16)-1) != nItemId )
+    if ( nItemId )
     {
         const size_t nItemPos = mpParent->GetItemPos( nItemId );
 
commit 243fa9392f1bbfaee41571b3d227535d1c49556a
Author: Matteo Casalin <matteo.casalin at gmx.com>
Date:   Sat Feb 18 16:09:42 2012 +0100

    ValueSet: replace some conditionals with simple arithmetic

diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
index 7150402..7f77215 100644
--- a/svtools/source/control/valueset.cxx
+++ b/svtools/source/control/valueset.cxx
@@ -430,10 +430,9 @@ void ValueSet::Format()
 
     // calculate number of rows
     mbScroll = false;
-    mnLines = (long)mItemList.size() / mnCols;
-    if ( mItemList.size() % mnCols )
-        mnLines++;
-    else if ( !mnLines )
+    // Floor( (M+N-1)/N )==Ceiling( M/N )
+    mnLines = (static_cast<long>(nItemCount)+mnCols-1) / mnCols;
+    if ( !mnLines )
         mnLines = 1;
 
     long nCalcHeight = aWinSize.Height()-nNoneHeight;
@@ -2298,10 +2297,9 @@ Size ValueSet::CalcWindowSizePixel( const Size& rItemSize, sal_uInt16 nDesireCol
                 nCalcLines = mnUserVisLines;
             else
             {
-                nCalcLines = mItemList.size() / nCalcCols;
-                if ( mItemList.size() % nCalcCols )
-                    nCalcLines++;
-                else if ( !nCalcLines )
+                // Floor( (M+N-1)/N )==Ceiling( M/N )
+                nCalcLines = (mItemList.size()+nCalcCols-1) / nCalcCols;
+                if ( !nCalcLines )
                     nCalcLines = 1;
             }
         }


More information about the Libreoffice-commits mailing list