Date: prev next · Thread: first prev next last
February 2012 Archives by date, by thread · List index


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


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.