On 02/24/2012 03:58 PM, Stefan Knorr (Astron) wrote:
I just want some early feedback from you so I don't implement it in the "wrong direction".There is one thing that I think you should change: zooming out should happen as before. Mouse-centered zooming out means that more often than not I land in the page background which isn't so useful.
After testing your suggestion and the reverse zoom out the later feels more natural to me. I have quickly adapted my patch to compare. By default the direction during zoom out is reversed to get back near the starting point. Additionally bReverseZoomOut in sd/source/ui/view/viewshel.cxx could be set to false to not change the center during zoom out. Regards Tim -- SUSE LINUX Products GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 16746 (AG Nürnberg) Maxfeldstr. 5, 90409 Nürnberg, Germany T: +49 (0) 911 74053-0 F: +49 (0) 911 74053-483 http://www.suse.de/
From 25a7be75f374aa3f28253594dc9454e20852ecd5 Mon Sep 17 00:00:00 2001 From: Tim Hardeck <thardeck@suse.com> Date: Fri, 24 Feb 2012 11:09:03 +0100 Subject: [PATCH] Mouse centered zooming for Impress/Draw concept This patch integrates mouse centered zooming for Impress/Draw. There is a tolerance area in the center where the direction isn't changed during zooming. Outside of it the position of the mouse is used to zoom in this direction. This is a just a concept patch for review by ux-advise not for submit. By default the direction during zoom out is reversed to get back near the starting point. Additionally bReverseZoomOut in sd/source/ui/view/viewshel.cxx could be set to false to not change the center during zoom out. --- sd/source/ui/inc/ViewShell.hxx | 2 +- sd/source/ui/inc/Window.hxx | 2 +- sd/source/ui/view/sdwindow.cxx | 51 +++++++++++++++++++++++++++++++++++++-- sd/source/ui/view/viewshe2.cxx | 4 +- sd/source/ui/view/viewshel.cxx | 16 +++++++++++- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 8a4a55a..e05c373 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -225,7 +225,7 @@ public: virtual void UpdateScrollBars (void); void Scroll(long nX, long nY); void ScrollLines(long nX, long nY); - virtual void SetZoom(long nZoom); + void SetZoom(long nZoom, const Point& rMousePos = Point(), bool bZoomIn = true); virtual void SetZoomRect(const Rectangle& rZoomRect); void InitWindows(const Point& rViewOrigin, const Size& rViewSize, const Point& rWinPos, sal_Bool bUpdate = sal_False); diff --git a/sd/source/ui/inc/Window.hxx b/sd/source/ui/inc/Window.hxx index 1842903..d340e2d 100644 --- a/sd/source/ui/inc/Window.hxx +++ b/sd/source/ui/inc/Window.hxx @@ -72,7 +72,7 @@ public: @param nZoom The zoom factor is given as integral percent value. */ - void SetZoomIntegral(long nZoom); + void SetZoomIntegral(long nZoom, const Point& rMousePos = Point(), bool bZoomIn = true); /** This internally used method performs the actual adaption of the window's map mode to the specified zoom factor. diff --git a/sd/source/ui/view/sdwindow.cxx b/sd/source/ui/view/sdwindow.cxx index 0590702..ac3aedc 100644 --- a/sd/source/ui/view/sdwindow.cxx +++ b/sd/source/ui/view/sdwindow.cxx @@ -487,7 +487,7 @@ long Window::SetZoomFactor(long nZoom) return nZoom; } -void Window::SetZoomIntegral(long nZoom) +void Window::SetZoomIntegral(long nZoom, const Point& rMousePos, bool bZoomIn) { // Clip the zoom factor to the valid range marked by nMinZoom as // previously calculated by <member>CalcMinZoom()</member> and the @@ -501,8 +501,53 @@ void Window::SetZoomIntegral(long nZoom) Size aSize = PixelToLogic(GetOutputSizePixel()); long nW = aSize.Width() * GetZoom() / nZoom; long nH = aSize.Height() * GetZoom() / nZoom; - maWinPos.X() += (aSize.Width() - nW) / 2; - maWinPos.Y() += (aSize.Height() - nH) / 2; + + // shift zooming direction + int nShiftX = 0; + int nShiftY = 0; + + // use mouse centered zooming if a mouse position is passed on + if(rMousePos != Point()) + { + // mouse area dimensions + Size wSize = GetOutputSizePixel(); + + const long MOUSE_X_TOLERANCE = Max((long) 10, wSize.Width() / 5); + const long MOUSE_Y_TOLERANCE = Max((long) 10, wSize.Height() / 5); + // the bigger the value the lower the shifts during zooming + const long SHIFT_SPEED_DIVISOR = 12; + + if((rMousePos.X() - wSize.Width() / 2) / MOUSE_X_TOLERANCE != 0) + { + if(rMousePos.X() < wSize.Width() / 2) + { + nShiftX -= nW / SHIFT_SPEED_DIVISOR; + } + else + { + nShiftX += nW / SHIFT_SPEED_DIVISOR; + } + if (!bZoomIn) + nShiftX *= -1; + } else printf("Center X\n"); + + if((rMousePos.Y() - wSize.Height() / 2) / MOUSE_Y_TOLERANCE != 0) + { + if(rMousePos.Y() < wSize.Height() / 2) + { + nShiftY -= nH / SHIFT_SPEED_DIVISOR; + } + else + { + nShiftY += nH / SHIFT_SPEED_DIVISOR; + } + if (!bZoomIn) + nShiftY *= -1; + } else printf("Center Y\n"); + } + + maWinPos.X() += (aSize.Width() - nW) / 2 + nShiftX; + maWinPos.Y() += (aSize.Height() - nH) / 2 + nShiftY; if ( maWinPos.X() < 0 ) maWinPos.X() = 0; if ( maWinPos.Y() < 0 ) maWinPos.Y() = 0; diff --git a/sd/source/ui/view/viewshe2.cxx b/sd/source/ui/view/viewshe2.cxx index cee898f..7d2f810 100644 --- a/sd/source/ui/view/viewshe2.cxx +++ b/sd/source/ui/view/viewshe2.cxx @@ -375,7 +375,7 @@ void ViewShell::Scroll(long nScrollX, long nScrollY) |* \************************************************************************/ -void ViewShell::SetZoom(long nZoom) +void ViewShell::SetZoom(long nZoom, const Point& rMousePos, bool bZoomIn) { Fraction aUIScale(nZoom, 100); aUIScale *= GetDoc()->GetUIScale(); @@ -388,7 +388,7 @@ void ViewShell::SetZoom(long nZoom) if (mpContentWindow.get() != NULL) { - mpContentWindow->SetZoomIntegral(nZoom); + mpContentWindow->SetZoomIntegral(nZoom, rMousePos, bZoomIn); // #i74769# Here is a 2nd way (besides Window::Scroll) to set the visible prt // of the window. It needs - like Scroll(SCROLL_CHILDREN) does - also to move diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index e4ae7f0..f5fee34 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -722,7 +722,21 @@ bool ViewShell::HandleScrollCommand(const CommandEvent& rCEvt, ::sd::Window* pWi else nNewZoom = Min( (long) pWin->GetMaxZoom(), basegfx::zoomtools::zoomIn( nOldZoom )); - SetZoom( nNewZoom ); + // for future option + bool bMouseCenteredZooming = true; + + // if activated the direction during zoom out is reverse + // otherwise the center isn't shifted during zoom out + bool bReverseZoomOut = true; + + if(bMouseCenteredZooming && (bReverseZoomOut || nOldZoom < nNewZoom)) { + SetZoom( nNewZoom, rCEvt.GetMousePosPixel(), nOldZoom < nNewZoom ); + } + else + { + SetZoom( nNewZoom ); + } + Invalidate( SID_ATTR_ZOOM ); Invalidate( SID_ATTR_ZOOMSLIDER ); -- 1.7.7
Attachment:
signature.asc
Description: OpenPGP digital signature