include/vcl/toolkit/scrbar.hxx |    9 +
 vcl/source/control/scrbar.cxx  |  221 +++++++++++++++++++++++++----------------
 2 files changed, 149 insertions(+), 81 deletions(-)

New commits:
commit 9d35ad8ee8aefedb5978f0c22aa08e1d9971c9b7
Author:     Christopher Sherlock <chris.sherloc...@gmail.com>
AuthorDate: Mon Dec 23 23:45:18 2024 +1100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Fri Feb 28 09:55:15 2025 +0100

    vcl: extract ScrollBar hit test functions
    
    ImplHitTestBtn1(), ImplHitTestBtn2(), ImplHitTestPageUp(),
    ImplHitTestPageDown() and ImplHitTestThumb() extracted and used.
    
    Extracted IsHorizontal() and GetScrollbarRegion() to reduce code
    duplication (also makes things arguably more clear - thanks to Michael
    Weghorn for pointing this out in review).
    
    Change-Id: Ibc9e584ab046046f2e6f1cd3056b8213973e3254
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179242
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/include/vcl/toolkit/scrbar.hxx b/include/vcl/toolkit/scrbar.hxx
index e8b9d37584ed..4199ae0bc636 100644
--- a/include/vcl/toolkit/scrbar.hxx
+++ b/include/vcl/toolkit/scrbar.hxx
@@ -81,6 +81,12 @@ private:
     SAL_DLLPRIVATE Size         getCurrentCalcSize() const;
     DECL_DLLPRIVATE_LINK( ImplAutoTimerHdl, Timer*, void );
 
+    bool ImplHitTestBtn1(const Point& rPt) const;
+    bool ImplHitTestBtn2(const Point& rPt) const;
+    bool ImplHitTestPageUp(const Point& rPt) const;
+    bool ImplHitTestPageDown(const Point& rPt) const;
+    bool ImplHitTestThumb(const Point& rPt) const;
+
 public:
     explicit        ScrollBar( vcl::Window* pParent, WinBits nStyle = WB_VERT 
);
     virtual         ~ScrollBar() override;
@@ -136,6 +142,9 @@ public:
     virtual Size    GetOptimalSize() const override;
 
     void            SetSwapArrows( bool bSwap ) { mbSwapArrows = bSwap; }
+
+    bool            IsHorizontal() const;
+    tools::Rectangle GetScrollbarRegion() const;
 };
 
 
diff --git a/vcl/source/control/scrbar.cxx b/vcl/source/control/scrbar.cxx
index fc56cc4be24a..6805ab59baf5 100644
--- a/vcl/source/control/scrbar.cxx
+++ b/vcl/source/control/scrbar.cxx
@@ -239,7 +239,6 @@ void ScrollBar::ImplCalc( bool bUpdate )
     {
         Size aOldSize = getCurrentCalcSize();
 
-        const tools::Rectangle aControlRegion( Point(0,0), aSize );
         tools::Rectangle aBtn1Region, aBtn2Region, aTrackRegion, 
aBoundingRegion;
         const bool bSwapArrows = mbSwapArrows || IsRTLEnabled();
 
@@ -248,12 +247,14 @@ void ScrollBar::ImplCalc( bool bUpdate )
         maPage1Rect = tools::Rectangle();
         maPage2Rect = tools::Rectangle();
 
+        const tools::Rectangle aScrollbarRegion = GetScrollbarRegion();
+
         if ( GetStyle() & WB_HORZ )
         {
             if ( GetNativeControlRegion( ControlType::Scrollbar, bSwapArrows? 
ControlPart::ButtonRight: ControlPart::ButtonLeft,
-                        aControlRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn1Region ) &&
+                        aScrollbarRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn1Region ) &&
                  GetNativeControlRegion( ControlType::Scrollbar, bSwapArrows? 
ControlPart::ButtonLeft: ControlPart::ButtonRight,
-                        aControlRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn2Region ) )
+                        aScrollbarRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn2Region ) )
             {
                 maBtn1Rect = aBtn1Region;
                 maBtn2Rect = aBtn2Region;
@@ -267,8 +268,8 @@ void ScrollBar::ImplCalc( bool bUpdate )
                 maBtn2Rect.SetSize( aBtnSize );
             }
 
-            if ( GetNativeControlRegion( ControlType::Scrollbar, 
ControlPart::TrackHorzArea,
-                     aControlRegion, ControlState::NONE, ImplControlValue(), 
aBoundingRegion, aTrackRegion ) )
+            if (GetNativeControlRegion( ControlType::Scrollbar, 
ControlPart::TrackHorzArea,
+                     aScrollbarRegion, ControlState::NONE, ImplControlValue(), 
aBoundingRegion, aTrackRegion ) )
                 maTrackRect = aTrackRegion;
             else
                 maTrackRect = tools::Rectangle::Normalize( 
maBtn1Rect.TopRight(), maBtn2Rect.BottomLeft() );
@@ -288,9 +289,9 @@ void ScrollBar::ImplCalc( bool bUpdate )
         else // WB_VERT
         {
             if ( GetNativeControlRegion( ControlType::Scrollbar, 
ControlPart::ButtonUp,
-                        aControlRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn1Region ) &&
+                        aScrollbarRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn1Region ) &&
                  GetNativeControlRegion( ControlType::Scrollbar, 
ControlPart::ButtonDown,
-                        aControlRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn2Region ) )
+                        aScrollbarRegion, ControlState::NONE, 
ImplControlValue(), aBoundingRegion, aBtn2Region ) )
             {
                 maBtn1Rect = aBtn1Region;
                 maBtn2Rect = aBtn2Region;
@@ -305,7 +306,7 @@ void ScrollBar::ImplCalc( bool bUpdate )
             }
 
             if ( GetNativeControlRegion( ControlType::Scrollbar, 
ControlPart::TrackVertArea,
-                     aControlRegion, ControlState::NONE, ImplControlValue(), 
aBoundingRegion, aTrackRegion ) )
+                     aScrollbarRegion, ControlState::NONE, ImplControlValue(), 
aBoundingRegion, aTrackRegion ) )
                 maTrackRect = aTrackRegion;
             else
                 maTrackRect = tools::Rectangle::Normalize( 
maBtn1Rect.BottomLeft()+Point(0,1), maBtn2Rect.TopRight() );
@@ -721,19 +722,11 @@ void ScrollBar::ImplDoMouseAction( const Point& 
rMousePos, bool bCallAction )
 {
     sal_uInt16  nOldStateFlags = mnStateFlags;
     bool    bAction = false;
-    bool        bHorizontal = ( GetStyle() & WB_HORZ ) != 0;
-    bool        bIsInside = false;
-
-    Point aPoint( 0, 0 );
-    tools::Rectangle aControlRegion( aPoint, GetOutputSizePixel() );
 
     switch ( meScrollType )
     {
         case ScrollType::LineUp:
-            if ( GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
(IsRTLEnabled()? ControlPart::ButtonRight: ControlPart::ButtonLeft): 
ControlPart::ButtonUp,
-                        aControlRegion, rMousePos, bIsInside )?
-                    bIsInside:
-                    maBtn1Rect.Contains( rMousePos ) )
+            if (ImplHitTestBtn1(rMousePos))
             {
                 bAction = bCallAction;
                 mnStateFlags |= SCRBAR_STATE_BTN1_DOWN;
@@ -743,10 +736,7 @@ void ScrollBar::ImplDoMouseAction( const Point& rMousePos, 
bool bCallAction )
             break;
 
         case ScrollType::LineDown:
-            if ( GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
(IsRTLEnabled()? ControlPart::ButtonLeft: ControlPart::ButtonRight): 
ControlPart::ButtonDown,
-                        aControlRegion, rMousePos, bIsInside )?
-                    bIsInside:
-                    maBtn2Rect.Contains( rMousePos ) )
+            if (ImplHitTestBtn2(rMousePos))
             {
                 bAction = bCallAction;
                 mnStateFlags |= SCRBAR_STATE_BTN2_DOWN;
@@ -757,10 +747,7 @@ void ScrollBar::ImplDoMouseAction( const Point& rMousePos, 
bool bCallAction )
 
         case ScrollType::PageUp:
             // HitTestNativeScrollbar, see remark at top of file
-            if ( GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
ControlPart::TrackHorzLeft: ControlPart::TrackVertUpper,
-                                       maPage1Rect, rMousePos, bIsInside )?
-                    bIsInside:
-                    maPage1Rect.Contains( rMousePos ) )
+            if (ImplHitTestPageUp(rMousePos))
             {
                 bAction = bCallAction;
                 mnStateFlags |= SCRBAR_STATE_PAGE1_DOWN;
@@ -771,10 +758,7 @@ void ScrollBar::ImplDoMouseAction( const Point& rMousePos, 
bool bCallAction )
 
         case ScrollType::PageDown:
             // HitTestNativeScrollbar, see remark at top of file
-            if ( GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
ControlPart::TrackHorzRight: ControlPart::TrackVertLower,
-                                       maPage2Rect, rMousePos, bIsInside )?
-                    bIsInside:
-                    maPage2Rect.Contains( rMousePos ) )
+            if (ImplHitTestPageDown(rMousePos))
             {
                 bAction = bCallAction;
                 mnStateFlags |= SCRBAR_STATE_PAGE2_DOWN;
@@ -792,6 +776,105 @@ void ScrollBar::ImplDoMouseAction( const Point& 
rMousePos, bool bCallAction )
         ImplDoAction( false );
 }
 
+bool ScrollBar::ImplHitTestBtn1(const Point& rPt) const
+{
+    ControlPart ePart;
+
+    if (IsHorizontal())
+    {
+        if (IsRTLEnabled())
+            ePart = ControlPart::ButtonRight;
+        else
+            ePart = ControlPart::ButtonLeft;
+    }
+    else
+    {
+        ePart = ControlPart::ButtonUp;
+    }
+
+    bool bIsInside = false;
+
+    if (GetOutDev()->HitTestNativeScrollbar(ePart, GetScrollbarRegion(), rPt, 
bIsInside))
+        return bIsInside;
+
+    return maBtn1Rect.Contains(rPt);
+}
+
+bool ScrollBar::ImplHitTestBtn2(const Point& rPt) const
+{
+    ControlPart ePart;
+
+    if (IsHorizontal())
+    {
+        if (IsRTLEnabled())
+            ePart = ControlPart::ButtonLeft;
+        else
+            ePart = ControlPart::ButtonRight;
+    }
+    else
+    {
+        ePart = ControlPart::ButtonDown;
+    }
+
+    bool bIsInside = false;
+
+    if (GetOutDev()->HitTestNativeScrollbar(ePart, GetScrollbarRegion(), rPt, 
bIsInside))
+        return bIsInside;
+
+    return maBtn2Rect.Contains(rPt);
+}
+
+bool ScrollBar::ImplHitTestPageUp(const Point& rPt) const
+{
+    ControlPart ePart;
+
+    if (IsHorizontal())
+        ePart = ControlPart::TrackHorzLeft;
+    else
+        ePart = ControlPart::TrackVertUpper;
+
+    bool bIsInside = false;
+
+    if (GetOutDev()->HitTestNativeScrollbar(ePart, maPage1Rect, rPt, 
bIsInside))
+        return bIsInside;
+
+    return maPage1Rect.Contains(rPt);
+}
+
+bool ScrollBar::ImplHitTestPageDown(const Point& rPt) const
+{
+    ControlPart ePart;
+
+    if (IsHorizontal())
+        ePart = ControlPart::TrackHorzRight;
+    else
+        ePart = ControlPart::TrackVertLower;
+
+    bool bIsInside = false;
+
+    if (GetOutDev()->HitTestNativeScrollbar(ePart, maPage2Rect, rPt, 
bIsInside))
+        return bIsInside;
+
+    return maPage2Rect.Contains(rPt);
+}
+
+bool ScrollBar::ImplHitTestThumb(const Point& rPt) const
+{
+    ControlPart ePart;
+
+    if (IsHorizontal())
+        ePart = ControlPart::ThumbHorz;
+    else
+        ePart = ControlPart::ThumbVert;
+
+    bool bIsInside = false;
+
+    if (GetOutDev()->HitTestNativeScrollbar(ePart, maThumbRect, rPt, 
bIsInside))
+        return bIsInside;
+
+    return maThumbRect.Contains(rPt);
+}
+
 void ScrollBar::ImplDragThumb( const Point& rMousePos )
 {
     tools::Long nMovePix;
@@ -831,6 +914,16 @@ void ScrollBar::ImplDragThumb( const Point& rMousePos )
     mnDelta = 0;
 }
 
+bool ScrollBar::IsHorizontal() const
+{
+    return (GetStyle() & WB_HORZ) != 0;
+}
+
+tools::Rectangle ScrollBar::GetScrollbarRegion() const
+{
+    return tools::Rectangle(Point(0, 0), GetOutputSizePixel());
+}
+
 void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt )
 {
     bool bPrimaryWarps = 
GetSettings().GetStyleSettings().GetPrimaryButtonWarpsSlider();
@@ -862,17 +955,10 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt )
     }
     const Point&        rMousePos = (GetMapMode().GetMapUnit() != 
MapUnit::MapTwip ? rMEvt.GetPosPixel() : aPosPixel);
     StartTrackingFlags  nTrackFlags = StartTrackingFlags::NONE;
-    bool                bHorizontal = ( GetStyle() & WB_HORZ ) != 0;
     bool                bIsInside = false;
     bool                bDragToMouse = false;
 
-    Point aPoint( 0, 0 );
-    tools::Rectangle aControlRegion( aPoint, GetOutputSizePixel() );
-
-    if ( GetOutDev()->HitTestNativeScrollbar( bHorizontal? (IsRTLEnabled()? 
ControlPart::ButtonRight: ControlPart::ButtonLeft): ControlPart::ButtonUp,
-                aControlRegion, rMousePos, bIsInside )?
-            bIsInside:
-            maBtn1Rect.Contains( rMousePos ) )
+    if (ImplHitTestBtn1(rMousePos))
     {
         if (rMEvt.IsLeft() && !(mnStateFlags & SCRBAR_STATE_BTN1_DISABLE) )
         {
@@ -880,10 +966,7 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt )
             meScrollType    = ScrollType::LineUp;
         }
     }
-    else if ( GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
(IsRTLEnabled()? ControlPart::ButtonLeft: ControlPart::ButtonRight): 
ControlPart::ButtonDown,
-                aControlRegion, rMousePos, bIsInside )?
-            bIsInside:
-            maBtn2Rect.Contains( rMousePos ) )
+    else if (ImplHitTestBtn2(rMousePos))
     {
         if (rMEvt.IsLeft() && !(mnStateFlags & SCRBAR_STATE_BTN2_DISABLE) )
         {
@@ -893,10 +976,7 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt )
     }
     else
     {
-        bool bThumbHit = GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
ControlPart::ThumbHorz : ControlPart::ThumbVert,
-                                               maThumbRect, rMousePos, 
bIsInside )
-                         ? bIsInside : maThumbRect.Contains( rMousePos );
-
+        bool bThumbHit = ImplHitTestThumb(rMousePos);
         bool bThumbAction = bWarp || bPage;
 
         bool bDragHandling = bWarp || (bThumbHit && bThumbAction);
@@ -938,17 +1018,14 @@ void ScrollBar::MouseButtonDown( const MouseEvent& rMEvt 
)
                 Invalidate();
             }
         }
-        else if(bPage && (!GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
ControlPart::TrackHorzArea : ControlPart::TrackVertArea,
-                                       aControlRegion, rMousePos, bIsInside ) 
||
+        else if(bPage && (!GetOutDev()->HitTestNativeScrollbar(IsHorizontal() 
? ControlPart::TrackHorzArea : ControlPart::TrackVertArea,
+                                       GetScrollbarRegion(), rMousePos, 
bIsInside ) ||
             bIsInside) )
         {
             nTrackFlags = StartTrackingFlags::ButtonRepeat;
 
             // HitTestNativeScrollbar, see remark at top of file
-            if ( GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
ControlPart::TrackHorzLeft : ControlPart::TrackVertUpper,
-                                       maPage1Rect, rMousePos, bIsInside )?
-                bIsInside:
-                maPage1Rect.Contains( rMousePos ) )
+            if (ImplHitTestPageUp(rMousePos))
             {
                 meScrollType    = ScrollType::PageUp;
             }
@@ -1220,42 +1297,24 @@ void ScrollBar::DataChanged( const DataChangedEvent& 
rDCEvt )
 
 tools::Rectangle* ScrollBar::ImplFindPartRect( const Point& rPt )
 {
-    bool    bHorizontal = ( GetStyle() & WB_HORZ ) != 0;
-    bool    bIsInside = false;
-
-    Point aPoint( 0, 0 );
-    tools::Rectangle aControlRegion( aPoint, GetOutputSizePixel() );
+    // HitTestNativeScrollbar, see remark at top of file
 
-    if( GetOutDev()->HitTestNativeScrollbar( bHorizontal? (IsRTLEnabled()? 
ControlPart::ButtonRight: ControlPart::ButtonLeft): ControlPart::ButtonUp,
-                aControlRegion, rPt, bIsInside )?
-            bIsInside:
-            maBtn1Rect.Contains( rPt ) )
+    if (ImplHitTestBtn1(rPt))
         return &maBtn1Rect;
-    else if( GetOutDev()->HitTestNativeScrollbar( bHorizontal? 
(IsRTLEnabled()? ControlPart::ButtonLeft: ControlPart::ButtonRight): 
ControlPart::ButtonDown,
-                aControlRegion, rPt, bIsInside )?
-            bIsInside:
-            maBtn2Rect.Contains( rPt ) )
+
+    if (ImplHitTestBtn2(rPt))
         return &maBtn2Rect;
-    // HitTestNativeScrollbar, see remark at top of file
-    else if( GetOutDev()->HitTestNativeScrollbar( bHorizontal ? 
ControlPart::TrackHorzLeft : ControlPart::TrackVertUpper,
-                maPage1Rect, rPt, bIsInside)?
-            bIsInside:
-            maPage1Rect.Contains( rPt ) )
+
+    if (ImplHitTestPageUp(rPt))
         return &maPage1Rect;
-    // HitTestNativeScrollbar, see remark at top of file
-    else if( GetOutDev()->HitTestNativeScrollbar( bHorizontal ? 
ControlPart::TrackHorzRight : ControlPart::TrackVertLower,
-                maPage2Rect, rPt, bIsInside)?
-            bIsInside:
-            maPage2Rect.Contains( rPt ) )
+
+    if (ImplHitTestPageDown(rPt))
         return &maPage2Rect;
-    // HitTestNativeScrollbar, see remark at top of file
-    else if( GetOutDev()->HitTestNativeScrollbar( bHorizontal ? 
ControlPart::ThumbHorz : ControlPart::ThumbVert,
-                maThumbRect, rPt, bIsInside)?
-             bIsInside:
-             maThumbRect.Contains( rPt ) )
+
+    if (ImplHitTestThumb(rPt))
         return &maThumbRect;
-    else
-        return nullptr;
+
+    return nullptr;
 }
 
 bool ScrollBar::PreNotify( NotifyEvent& rNEvt )

Reply via email to