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