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 )