Hi, 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. I have set a tolerance area of 20% but it could be easily changed. It is bigger than it does look. I have only used one shift speed which could also be adjusted. I just want some early feedback from you so I don't implement it in the "wrong direction". 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 f88813e80d7737e353f67002a18b6b5d6ca566a9 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. --- sd/source/ui/inc/ViewShell.hxx | 2 +- sd/source/ui/inc/Window.hxx | 2 +- sd/source/ui/view/sdwindow.cxx | 47 +++++++++++++++++++++++++++++++++++++-- sd/source/ui/view/viewshe2.cxx | 4 +- sd/source/ui/view/viewshel.cxx | 11 ++++++++- 5 files changed, 58 insertions(+), 8 deletions(-) diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 8a4a55a..0c00721 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()); 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..8ed56ac 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()); /** 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..224166e 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) { // Clip the zoom factor to the valid range marked by nMinZoom as // previously calculated by <member>CalcMinZoom()</member> and the @@ -501,8 +501,49 @@ 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; + } + } 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; + } + } 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..1ca7f4e 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) { 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); // #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..a12b175 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -722,7 +722,16 @@ 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(bMouseCenteredZooming) { + SetZoom( nNewZoom, rCEvt.GetMousePosPixel() ); + } + else + { + SetZoom( nNewZoom ); + } + Invalidate( SID_ATTR_ZOOM ); Invalidate( SID_ATTR_ZOOMSLIDER ); -- 1.7.7
Attachment:
signature.asc
Description: OpenPGP digital signature