tdf#119745: Fix touchpad scrolling for Slides and Pages panes.
Use fractional lines scrolled to calculate distance to scroll view, instead of jumping forward or backward a full page every call based on sign. Also fixes existing bugs: horizontal pane can scroll too far to right; and snapping pane from vertical to horizontal can break scrolling if view partially scrolled. Change-Id: I0ead4710a296aac26f1cf1a0fc48e6ea403271a6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177836 Tested-by: Jenkins Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
This commit is contained in:
parent
18399240f2
commit
143e89dbf8
5 changed files with 61 additions and 42 deletions
|
@ -382,6 +382,9 @@ bool SlideSorterController::Command (
|
|||
// We do not support zooming with control+mouse wheel.
|
||||
return false;
|
||||
}
|
||||
// tdf#119745: ScrollLines gives accurate distance scrolled on touchpad. NotchDelta sign
|
||||
// gives direction. Default is 3 lines at a time, so factor that out.
|
||||
double scrollDistance = -pData->GetScrollLines() * pData->GetNotchDelta() / 3.0;
|
||||
// Determine whether to scroll horizontally or vertically. This
|
||||
// depends on the orientation of the scroll bar and the
|
||||
// IsHoriz() flag of the event.
|
||||
|
@ -390,13 +393,13 @@ bool SlideSorterController::Command (
|
|||
{
|
||||
GetScrollBarManager().Scroll(
|
||||
ScrollBarManager::Orientation_Vertical,
|
||||
-pData->GetNotchDelta());
|
||||
scrollDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetScrollBarManager().Scroll(
|
||||
ScrollBarManager::Orientation_Horizontal,
|
||||
-pData->GetNotchDelta());
|
||||
scrollDistance);
|
||||
}
|
||||
mrSlideSorter.GetView().UpdatePageUnderMouse(rEvent.GetMousePosPixel());
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ IMPL_LINK_NOARG(ScrollBarManager, AutoScrollTimeoutHandler, Timer *, void)
|
|||
|
||||
void ScrollBarManager::Scroll(
|
||||
const Orientation eOrientation,
|
||||
const sal_Int32 nDistance)
|
||||
const double nDistance)
|
||||
{
|
||||
bool bIsVertical (false);
|
||||
switch (eOrientation)
|
||||
|
@ -528,51 +528,53 @@ void ScrollBarManager::Scroll(
|
|||
return;
|
||||
}
|
||||
|
||||
Point aNewTopLeft (
|
||||
mpHorizontalScrollBar ? mpHorizontalScrollBar->GetThumbPos() : 0,
|
||||
mpVerticalScrollBar ? mpVerticalScrollBar->GetThumbPos() : 0);
|
||||
// Get current scrolling view position
|
||||
// Fix bug where 1) scrolling view is partially scrolled, 2) view window is snapped from vertical
|
||||
// to horizontal or vice-versa, then 3) mouse wheel scrolled. Scrolling broke because we got an
|
||||
// invalid starting position from the scrollbar that's no longer displayed. Check scrollbars
|
||||
// visible before getting position from each.
|
||||
bool bHorizontalScrollShown = mpHorizontalScrollBar && mpHorizontalScrollBar->IsVisible();
|
||||
bool bVerticalScrollShown = mpVerticalScrollBar && mpVerticalScrollBar->IsVisible();
|
||||
Point aNewTopLeft(
|
||||
bHorizontalScrollShown ? mpHorizontalScrollBar->GetThumbPos() : 0,
|
||||
bVerticalScrollShown ? mpVerticalScrollBar->GetThumbPos() : 0);
|
||||
|
||||
view::Layouter& rLayouter (mrSlideSorter.GetView().GetLayouter());
|
||||
|
||||
// Calculate estimate of new location.
|
||||
// Calculate new location
|
||||
Size objectSize( rLayouter.GetPageObjectSize() ); // Size of a page in pane
|
||||
Size objectAndGapSize = view::Layouter::AddGap(objectSize); // Add gap between pages to size
|
||||
if (bIsVertical)
|
||||
aNewTopLeft.AdjustY(nDistance * rLayouter.GetPageObjectSize().Height() );
|
||||
aNewTopLeft.AdjustY(nDistance * objectAndGapSize.Height() ); // New position
|
||||
else
|
||||
aNewTopLeft.AdjustX(nDistance * rLayouter.GetPageObjectSize().Width() );
|
||||
aNewTopLeft.AdjustX(nDistance * objectAndGapSize.Width() ); // New position
|
||||
|
||||
// Adapt location to show whole slides.
|
||||
// Get displayable area for pages
|
||||
::tools::Rectangle scrollArea = rLayouter.GetTotalBoundingBox();
|
||||
|
||||
// Prevent scrolling out of bounds by limiting scroll destination point.
|
||||
if (bIsVertical)
|
||||
if (nDistance > 0)
|
||||
{
|
||||
const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
|
||||
Point(aNewTopLeft.X(), aNewTopLeft.Y()+mpVerticalScrollBar->GetVisibleSize()),
|
||||
true));
|
||||
aNewTopLeft.setY( rLayouter.GetPageObjectBox(nIndex,true).Bottom()
|
||||
- mpVerticalScrollBar->GetVisibleSize() );
|
||||
}
|
||||
else
|
||||
{
|
||||
const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
|
||||
Point(aNewTopLeft.X(), aNewTopLeft.Y()),
|
||||
true));
|
||||
aNewTopLeft.setY( rLayouter.GetPageObjectBox(nIndex,true).Top() );
|
||||
}
|
||||
{
|
||||
// Subtract size of view itself to get scrollable area.
|
||||
::tools::Long scrollbarSize = mpVerticalScrollBar->GetVisibleSize();
|
||||
// Prevent (-) height. std::max needs type specified explicitly so params match.
|
||||
::tools::Long scrollHeight = std::max(static_cast<::tools::Long>(0), scrollArea.GetHeight() - scrollbarSize);
|
||||
scrollArea.SetHeight(scrollHeight);
|
||||
// Constrain scroll point to valid area
|
||||
::tools::Long constrainedY = std::clamp(aNewTopLeft.getY(), scrollArea.Top(), scrollArea.Bottom());
|
||||
aNewTopLeft.setY(constrainedY);
|
||||
}
|
||||
else
|
||||
if (nDistance > 0)
|
||||
{
|
||||
const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
|
||||
Point(aNewTopLeft.X()+mpVerticalScrollBar->GetVisibleSize(), aNewTopLeft.Y()),
|
||||
true));
|
||||
aNewTopLeft.setX( rLayouter.GetPageObjectBox(nIndex,true).Right()
|
||||
- mpVerticalScrollBar->GetVisibleSize() );
|
||||
}
|
||||
else
|
||||
{
|
||||
const sal_Int32 nIndex (rLayouter.GetIndexAtPoint(
|
||||
Point(aNewTopLeft.X(), aNewTopLeft.Y()),
|
||||
true));
|
||||
aNewTopLeft.setX( rLayouter.GetPageObjectBox(nIndex,true).Left() );
|
||||
}
|
||||
{
|
||||
// Subtract size of view itself to get scrollable area.
|
||||
::tools::Long scrollbarSize = mpHorizontalScrollBar->GetVisibleSize();
|
||||
// Prevent (-) width. std::max needs type specified explicitly so params match.
|
||||
::tools::Long scrollWidth = std::max(static_cast<::tools::Long>(0), scrollArea.GetWidth() - scrollbarSize);
|
||||
scrollArea.SetWidth(scrollWidth);
|
||||
// Constrain scroll point to valid area
|
||||
::tools::Long constrainedX = std::clamp(aNewTopLeft.getX(), scrollArea.Left(), scrollArea.Right());
|
||||
aNewTopLeft.setX(constrainedX);
|
||||
}
|
||||
|
||||
mrSlideSorter.GetController().GetVisibleAreaManager().DeactivateCurrentSlideTracking();
|
||||
SetTopLeft(aNewTopLeft);
|
||||
|
|
|
@ -155,7 +155,7 @@ public:
|
|||
*/
|
||||
void Scroll(
|
||||
const Orientation eOrientation,
|
||||
const sal_Int32 nDistance);
|
||||
const double nDistance);
|
||||
|
||||
private:
|
||||
SlideSorter& mrSlideSorter;
|
||||
|
|
|
@ -111,6 +111,12 @@ public:
|
|||
|
||||
Size const & GetPageObjectSize() const;
|
||||
|
||||
/** Returns the passed Size plus the gap between pages.
|
||||
@param rObjectSize
|
||||
Object size to start from.
|
||||
*/
|
||||
static Size AddGap(const Size & rObjectSize);
|
||||
|
||||
/** Return the bounding box in window coordinates of the nIndex-th page
|
||||
object.
|
||||
*/
|
||||
|
|
|
@ -183,7 +183,7 @@ public:
|
|||
const sal_Int32 nColumn,
|
||||
const bool bClampToValidRange) const;
|
||||
|
||||
::tools::Rectangle GetPageObjectBox (
|
||||
::tools::Rectangle GetPageObjectBox (
|
||||
const sal_Int32 nIndex,
|
||||
const bool bIncludeBorderAndGap = false) const;
|
||||
|
||||
|
@ -349,6 +349,14 @@ Size const & Layouter::GetPageObjectSize() const
|
|||
return mpImplementation->maPageObjectSize;
|
||||
}
|
||||
|
||||
Size Layouter::AddGap(const Size & rObjectSize)
|
||||
{
|
||||
Size newSize = rObjectSize;
|
||||
newSize.AdjustWidth(Implementation::gnHorizontalGap);
|
||||
newSize.AdjustHeight(Implementation::gnVerticalGap);
|
||||
return newSize;
|
||||
}
|
||||
|
||||
::tools::Rectangle Layouter::GetPageObjectBox (
|
||||
const sal_Int32 nIndex,
|
||||
const bool bIncludeBorderAndGap) const
|
||||
|
|
Loading…
Reference in a new issue