diff options
author | Jonas Eyov <jeyov@proton.me> | 2022-11-18 03:40:57 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2022-11-21 17:28:45 +0100 |
commit | fe21365c5a9083ae1f086ea48614263b3a75ab3e (patch) | |
tree | 0d3047180d5328464c3c8ac07cc64c78480f0181 /vcl/source/window/window2.cxx | |
parent | 17cfd43e28c45626b1e0990bd0e51fdc97409ebe (diff) |
tdf#143209 vcl: track partial scroll deltas
this makes scrolling in calc smoother and makes left/up scrolling
the same speed as right/down scrolling, which was previously not the
case.
prior to this change, Window::HandleScrollCommand only checked each
event for being a large enough scroll to advance one unit. this
happened in lcl_HandleScrollHelper by way of o3tl::saturating_cast,
which meant that nonzero upward/leftward scrolls were always worth at
least one unit, while downward/rightward scrolls needed to be larger
than 1 to count.
now, we accumulate partial scroll offsets in WindowImpl and perform a
saturating cast on the absolute value, so behavior is symmetric and
sensitive to accumulated small scroll values. this feels smoother
and is more correct.
Change-Id: Id3692d14edd45ed26f2952e3418e4d82806e1fc4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142948
Tested-by: Jenkins
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source/window/window2.cxx')
-rw-r--r-- | vcl/source/window/window2.cxx | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx index b6c4ee25415a..978dc0b6ecf8 100644 --- a/vcl/source/window/window2.cxx +++ b/vcl/source/window/window2.cxx @@ -598,12 +598,14 @@ tools::Long Window::GetDrawPixel( OutputDevice const * pDev, tools::Long nPixels return nP; } -static void lcl_HandleScrollHelper( Scrollable* pScrl, double nN, bool isMultiplyByLineSize ) +// returns how much was actually scrolled (so that abs(retval) <= abs(nN)) +static double lcl_HandleScrollHelper( Scrollable* pScrl, double nN, bool isMultiplyByLineSize ) { if (!pScrl || !nN || pScrl->Inactive()) - return; + return 0.0; tools::Long nNewPos = pScrl->GetThumbPos(); + double scrolled = nN; if ( nN == double(-LONG_MAX) ) nNewPos += pScrl->GetPageSize(); @@ -616,13 +618,22 @@ static void lcl_HandleScrollHelper( Scrollable* pScrl, double nN, bool isMultipl nN*=pScrl->GetLineSize(); } - const double fVal = nNewPos - nN; + // compute how many quantized units to scroll + tools::Long magnitude = o3tl::saturating_cast<tools::Long>(abs(nN)); + tools::Long change = copysign(magnitude, nN); + + nNewPos = nNewPos - change; - nNewPos = o3tl::saturating_cast<tools::Long>(fVal); + scrolled = double(change); + // convert back to chunked/continuous + if(isMultiplyByLineSize){ + scrolled /= pScrl->GetLineSize(); + } } pScrl->DoScroll( nNewPos ); + return scrolled; } bool Window::HandleScrollCommand( const CommandEvent& rCmd, @@ -668,6 +679,9 @@ bool Window::HandleScrollCommand( const CommandEvent& rCmd, { double nScrollLines = pData->GetScrollLines(); double nLines; + double* partialScroll = pData->IsHorz() + ? &mpWindowImpl->mfPartialScrollX + : &mpWindowImpl->mfPartialScrollY; if ( nScrollLines == COMMAND_WHEEL_PAGESCROLL ) { if ( pData->GetDelta() < 0 ) @@ -676,13 +690,12 @@ bool Window::HandleScrollCommand( const CommandEvent& rCmd, nLines = double(LONG_MAX); } else - nLines = pData->GetNotchDelta() * nScrollLines; + nLines = *partialScroll + pData->GetNotchDelta() * nScrollLines; if ( nLines ) { - ImplHandleScroll( nullptr, - 0L, - pData->IsHorz() ? pHScrl : pVScrl, - nLines ); + Scrollable* pScrl = pData->IsHorz() ? pHScrl : pVScrl; + double scrolled = lcl_HandleScrollHelper( pScrl, nLines, true ); + *partialScroll = nLines - scrolled; bRet = true; } } @@ -806,12 +819,6 @@ bool Window::HandleScrollCommand( const CommandEvent& rCmd, return bRet; } -// Note that when called for CommandEventId::Wheel above, despite its name, -// pVScrl isn't necessarily the vertical scroll bar. Depending on -// whether the scroll is horizontal or vertical, it is either the -// horizontal or vertical scroll bar. nY is correspondingly either -// the horizontal or vertical scroll amount. - void Window::ImplHandleScroll( Scrollable* pHScrl, double nX, Scrollable* pVScrl, double nY ) { |