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


Hi,

this patch integrates mouse centered zooming. 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.

I have also added cursor centered zooming for Writer because it was the
only LO application with an unintuitive zooming behavior.
So if mouse centered zooming is disabled (in the concept just set
bMouseCenteredZooming to false) the cursor is used as the center
instead of the upper left corner.

Mouse centered zooming should work in Calc, Draw, Impress and Writer but
the code is still messy.
If it is Ok this way I try to clean it up and reduce redundancy.

We should also discuss how big the center area is supposed to be, if it
should be different for some LO application and how fast the location
should be shifted during zooming.

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 a00659dbc53cac7a67956da10ffddd9a316a5b0d Mon Sep 17 00:00:00 2001
From: Tim Hardeck <thardeck@suse.com>
Date: Thu, 15 Mar 2012 19:05:50 +0100
Subject: [PATCH] Mouse centered zooming concept

This patch integrates mouse centered zooming. 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.

I have also added cursor centered zooming for Writer because it was the
only LO application with an unintuitive zooming behavior.
So if mouse centered zooming is disabled (in the concept just set
bMouseCenteredZooming to false) the cursor is used as the center
instead of the upper left corner.
---
 sc/source/ui/inc/tabview.hxx           |    2 +-
 sc/source/ui/inc/viewdata.hxx          |    4 +-
 sc/source/ui/view/tabview.cxx          |    6 ++-
 sc/source/ui/view/tabview5.cxx         |    4 +-
 sc/source/ui/view/viewdata.cxx         |   63 +++++++++++++++++++++++++---
 sd/source/ui/inc/ViewShell.hxx         |    2 +-
 sd/source/ui/inc/Window.hxx            |    2 +-
 sd/source/ui/view/sdwindow.cxx         |   52 +++++++++++++++++++++-
 sd/source/ui/view/viewshe2.cxx         |    4 +-
 sd/source/ui/view/viewshel.cxx         |   16 +++++++-
 svx/source/stbctrls/zoomsliderctrl.cxx |    4 +-
 sw/source/ui/inc/view.hxx              |    4 +-
 sw/source/ui/uiview/viewmdi.cxx        |   73 +++++++++++++++++++++++++++++--
 sw/source/ui/uiview/viewport.cxx       |   12 ++++--
 14 files changed, 215 insertions(+), 33 deletions(-)

diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index 8879b07..bf60b58 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -310,7 +310,7 @@ public:
      * @param bSameTabButMoved true if the same sheet as before is activated.
      */
     void            TabChanged( bool bSameTabButMoved = false );
-    void            SetZoom( const Fraction& rNewX, const Fraction& rNewY, bool bAll );
+    void            SetZoom( const Fraction& rNewX, const Fraction& rNewY, bool bAll, const Point& 
rMousePos = Point(), bool bZoomIn = true );
     SC_DLLPUBLIC void            RefreshZoom();
     void            SetPagebreakMode( bool bSet );
 
diff --git a/sc/source/ui/inc/viewdata.hxx b/sc/source/ui/inc/viewdata.hxx
index f2ba7d5..7af0d67 100644
--- a/sc/source/ui/inc/viewdata.hxx
+++ b/sc/source/ui/inc/viewdata.hxx
@@ -321,8 +321,8 @@ public:
 
     void            SetZoomType( SvxZoomType eNew, sal_Bool bAll );
     void            SetZoomType( SvxZoomType eNew, std::vector< SCTAB >& tabs );
-    void            SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& 
tabs );
-    void            SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll );
+    void            SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& 
tabs, const Point& rMousePos = Point(), bool bZoomIn = true );
+    void            SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll, const 
Point& rMousePos = Point(), bool bZoomIn = true );
     void            RefreshZoom();
 
     void            SetSelCtrlMouseClick( bool bTmp ) { bSelCtrlMouseClick = bTmp; }
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index a2784e1..202d458 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -1056,10 +1056,14 @@ bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
             //  and can't be changed directly
 
             const Fraction& rOldY = aViewData.GetZoomY();
+            bool bZoomIn = true;
             long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
             long nNew = nOld;
             if ( pData->GetDelta() < 0 )
+            {
                 nNew = Max( (long) MINZOOM, basegfx::zoomtools::zoomOut( nOld ));
+                bZoomIn = false;
+            }
             else
                 nNew = Min( (long) MAXZOOM, basegfx::zoomtools::zoomIn( nOld ));
 
@@ -1070,7 +1074,7 @@ bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
                 sal_Bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
                 SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
                 Fraction aFract( nNew, 100 );
-                SetZoom( aFract, aFract, bSyncZoom );
+                SetZoom( aFract, aFract, bSyncZoom ,rCEvt.GetMousePosPixel(), bZoomIn );
                 PaintGrid();
                 PaintTop();
                 PaintLeft();
diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx
index 3d30fad..64ac6d8 100644
--- a/sc/source/ui/view/tabview5.cxx
+++ b/sc/source/ui/view/tabview5.cxx
@@ -387,9 +387,9 @@ void ScTabView::SetZoomType( SvxZoomType eNew, bool bAll )
     aViewData.SetZoomType( eNew, bAll );
 }
 
-void ScTabView::SetZoom( const Fraction& rNewX, const Fraction& rNewY, bool bAll )
+void ScTabView::SetZoom( const Fraction& rNewX, const Fraction& rNewY, bool bAll, const Point& 
rMousePos, bool bZoomIn )
 {
-    aViewData.SetZoom( rNewX, rNewY, bAll );
+    aViewData.SetZoom( rNewX, rNewY, bAll, rMousePos, bZoomIn );
     if (pDrawView)
         pDrawView->RecalcScale();
     ZoomChanged();              // einzeln wegen CLOOKs
diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index a0f4cdf..55c0de2 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -601,8 +601,61 @@ void ScViewData::SetZoomType( SvxZoomType eNew, sal_Bool bAll )
     SetZoomType( eNew, vTabs );
 }
 
-void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& tabs 
)
+void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& 
tabs, const Point& rMousePos, bool bZoomIn )
 {
+    // use mouse centered zooming if a mouse position is passed on
+    if(rMousePos != Point())
+    {
+        const long MOUSE_X_TOLERANCE = Max((long) 10, aScrSize.Width() / 4);
+        const long MOUSE_Y_TOLERANCE = Max((long) 10, aScrSize.Height() / 4);
+
+
+        SCCOL nX1 = GetPosX(SC_SPLIT_LEFT);
+        SCCOL nY1 = GetPosY(SC_SPLIT_BOTTOM);
+
+        SCCOL nShiftX = 0;
+        SCCOL nShiftY = 0;
+
+        if((rMousePos.X() - aScrSize.Width() / 2) / MOUSE_X_TOLERANCE != 0)
+        {
+            if(rMousePos.X() < aScrSize.Width() / 2)
+            {
+                nShiftX--;
+            }
+            else
+            {
+                nShiftX++;
+            }
+            if (!bZoomIn)
+                nShiftX *= -1;
+        } else printf("Center X\n");
+
+        if((rMousePos.Y() - aScrSize.Height() / 2) / MOUSE_Y_TOLERANCE != 0)
+        {
+            if(rMousePos.Y() < aScrSize.Height() / 2)
+            {
+                nShiftY--;
+            }
+            else
+            {
+                nShiftY++;
+            }
+            if (!bZoomIn)
+                nShiftY *= -1;
+        } else printf("Center Y\n");
+        printf("-------------\n\n");
+
+        nX1 += nShiftX;
+        nY1 += nShiftY;
+
+        nX1 = Max(0, (int)nX1);
+        nY1 = Max(0, (int)nY1);
+
+        SetActivePart( SC_SPLIT_BOTTOMLEFT );
+        SetPosX( SC_SPLIT_LEFT, nX1 );
+        SetPosY( SC_SPLIT_BOTTOM, nY1 );
+    }
+
     sal_Bool bAll = ( tabs.empty() );
     if ( !bAll ) // create associated table data
         CreateTabData( tabs );
@@ -620,7 +673,6 @@ void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vec
         aValidY = aFrac20;
     if (aValidY>aFrac400)
         aValidY = aFrac400;
-
     if ( bAll )
     {
         for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabData.size()); ++i )
@@ -675,7 +727,7 @@ void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vec
     RefreshZoom();
 }
 
-void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll )
+void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll, const 
Point& rMousePos, bool bZoomIn )
 {
     std::vector< SCTAB > vTabs;
     if ( !bAll ) // get selected tabs
@@ -683,7 +735,7 @@ void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool
         ScMarkData::iterator itr = mpMarkData->begin(), itrEnd = mpMarkData->end();
         vTabs.insert(vTabs.begin(), itr, itrEnd);
     }
-    SetZoom( rNewX, rNewY, vTabs );
+    SetZoom( rNewX, rNewY, vTabs, rMousePos, bZoomIn );
 }
 
 void ScViewData::SetShowGrid( bool bShow )
@@ -695,7 +747,6 @@ void ScViewData::SetShowGrid( bool bShow )
 void ScViewData::RefreshZoom()
 {
     // recalculate zoom-dependent values (only for current sheet)
-
     CalcPPT();
     RecalcPixPos();
     aScenButSize = Size(0,0);
@@ -1933,7 +1984,7 @@ void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY )
         pThisTab->nPosY[eWhich] = 0;
 }
 
-void ScViewData::RecalcPixPos()             // nach Zoom-Aenderungen
+void ScViewData::RecalcPixPos()             // after zoom change
 {
     for (sal_uInt16 eWhich=0; eWhich<2; eWhich++)
     {
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..eb83dc6 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,54 @@ 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
+    long nShiftX = 0;
+    long 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");
+        printf("-------------\n\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 );
 
diff --git a/svx/source/stbctrls/zoomsliderctrl.cxx b/svx/source/stbctrls/zoomsliderctrl.cxx
index 66b5d4d..afab9c4 100644
--- a/svx/source/stbctrls/zoomsliderctrl.cxx
+++ b/svx/source/stbctrls/zoomsliderctrl.cxx
@@ -359,11 +359,11 @@ sal_Bool SvxZoomSliderControl::MouseButtonDown( const MouseEvent & rEvt )
 
     // click to - button
     if ( nXDiff >= nButtonLeftOffset && nXDiff <= nButtonRightOffset )
-        mpImpl->mnCurrentZoom = basegfx::zoomtools::zoomOut( 
static_cast<int>(mpImpl->mnCurrentZoom) );
+        mpImpl->mnCurrentZoom = basegfx::zoomtools::zoomOut( mpImpl->mnCurrentZoom );
     // click to + button
     else if ( nXDiff >= aControlRect.GetWidth() - nSliderXOffset + nButtonLeftOffset &&
               nXDiff <= aControlRect.GetWidth() - nSliderXOffset + nButtonRightOffset )
-        mpImpl->mnCurrentZoom = basegfx::zoomtools::zoomIn( 
static_cast<int>(mpImpl->mnCurrentZoom) );
+        mpImpl->mnCurrentZoom = basegfx::zoomtools::zoomIn( mpImpl->mnCurrentZoom );
     // click to slider
     else if( nXDiff >= nSliderXOffset && nXDiff <= aControlRect.GetWidth() - nSliderXOffset )
         mpImpl->mnCurrentZoom = Offset2Zoom( nXDiff );
diff --git a/sw/source/ui/inc/view.hxx b/sw/source/ui/inc/view.hxx
index 229e8f5..d7faa5c 100644
--- a/sw/source/ui/inc/view.hxx
+++ b/sw/source/ui/inc/view.hxx
@@ -365,7 +365,7 @@ class SW_DLLPUBLIC SwView: public SfxViewShell
     SW_DLLPRIVATE void          _SetZoom( const Size &rEditSz,
                               SvxZoomType eZoomType,
                               short nFactor = 100,
-                              sal_Bool bViewOnly = sal_False);
+                              sal_Bool bViewOnly = sal_False, const Point& rMousePos = Point(), 
bool bZoomIn = true);
     SW_DLLPRIVATE void          CalcAndSetBorderPixel( SvBorder &rToFill, sal_Bool bInner );
 
     SW_DLLPRIVATE void          ShowAtResize();
@@ -506,7 +506,7 @@ public:
     // insert frames
     void            InsFrmMode(sal_uInt16 nCols);
 
-    void            SetZoom( SvxZoomType eZoomType, short nFactor = 100, sal_Bool bViewOnly = 
sal_False);
+    void            SetZoom( SvxZoomType eZoomType, short nFactor = 100, sal_Bool bViewOnly = 
sal_False,  const Point& rMousePos = Point(), bool bZoomIn = true );
     virtual void    SetZoomFactor( const Fraction &rX, const Fraction & );
 
     void            SetViewLayout( sal_uInt16 nColumns, bool bBookMode, sal_Bool bViewOnly = 
sal_False );
diff --git a/sw/source/ui/uiview/viewmdi.cxx b/sw/source/ui/uiview/viewmdi.cxx
index 27949cf..cc3c6fd 100644
--- a/sw/source/ui/uiview/viewmdi.cxx
+++ b/sw/source/ui/uiview/viewmdi.cxx
@@ -71,13 +71,13 @@ sal_Int32 SwView::nActMark = 0;
 using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::frame;
 
-void SwView::SetZoom( SvxZoomType eZoomType, short nFactor, sal_Bool bViewOnly )
+void SwView::SetZoom( SvxZoomType eZoomType, short nFactor, sal_Bool bViewOnly, const Point& 
rMousePos, bool bZoomIn )
 {
-    _SetZoom( GetEditWin().GetOutputSizePixel(), eZoomType, nFactor, bViewOnly );
+    _SetZoom( GetEditWin().GetOutputSizePixel(), eZoomType, nFactor, bViewOnly, rMousePos, bZoomIn 
);
 }
 
 void SwView::_SetZoom( const Size &rEditSize, SvxZoomType eZoomType,
-                        short nFactor, sal_Bool bViewOnly )
+                        short nFactor, sal_Bool bViewOnly,  const Point& rMousePos, bool bZoomIn )
 {
     sal_Bool bUnLockView = !pWrtShell->IsViewLocked();
     pWrtShell->LockView( sal_True );
@@ -85,7 +85,6 @@ void SwView::_SetZoom( const Size &rEditSize, SvxZoomType eZoomType,
 
     {
     ACT_KONTEXT(pWrtShell);
-
     long nFac = nFactor;
 
     sal_Bool bWeb = 0 != PTR_CAST(SwWebView, this);
@@ -167,6 +166,69 @@ void SwView::_SetZoom( const Size &rEditSize, SvxZoomType eZoomType,
         }
         if ( pOpt->GetZoom() != (sal_uInt16) nFac )
         {
+            bool bMouseCenteredZooming = true;
+            if( bMouseCenteredZooming )
+                {
+                // use mouse centered zooming if a mouse position is passed on
+                if( rMousePos != Point() )
+                {
+                    Size aSize = GetEditWin().PixelToLogic(rEditSize);
+                    long nW = aSize.Width()  * pOpt->GetZoom() / nFac;
+                    long nH = aSize.Height() * pOpt->GetZoom() / nFac;
+                    Point aPos = aVisArea.TopLeft();
+                    const long MOUSE_X_TOLERANCE = Max((long) 10, rEditSize.Width() / 5);
+                    const long MOUSE_Y_TOLERANCE = Max((long) 10, rEditSize.Height() / 5);
+
+                    // the bigger the value the lower the shifts during zooming
+                    const long SHIFT_SPEED_DIVISOR = 4;
+                    long nShiftX = 0, nShiftY = 0;
+                    if((rMousePos.X() - rEditSize.Width() / 2) / MOUSE_X_TOLERANCE != 0)
+                    {
+                        if(rMousePos.X() < rEditSize.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() - rEditSize.Height() / 2) / MOUSE_Y_TOLERANCE != 0)
+                    {
+                        if(rMousePos.Y() < rEditSize.Height() / 2)
+                        {
+                            nShiftY -=  nH / SHIFT_SPEED_DIVISOR;
+                        }
+                        else
+                        {
+                            nShiftY +=  nH / SHIFT_SPEED_DIVISOR;
+                        }
+                        if (!bZoomIn)
+                            nShiftY *= -1;
+                    } else printf("Center Y\n");
+                    printf("-------------\n\n");
+                    aPos.X() += (aSize.Width()  - nW) / 2 + nShiftX;
+                    aPos.Y() += (aSize.Height() - nH) / 2 + nShiftY;
+                    aPos.X() = Max( 0L, aPos.X());
+                    aPos.Y() = Max( 0L, aPos.Y());
+                    SetVisArea( aPos );
+                }
+            }
+            else
+            {
+                // center the screen on the cursor
+                Point aPos;
+                const SwRect &rCharRect = pWrtShell->GetCharRect();
+                Size aTest = GetEditWin().PixelToLogic( rEditSize );
+                aPos.X() = rCharRect.Left() - aTest.Width() / 2;
+                aPos.Y() = rCharRect.Top() - aTest.Height() / 2;
+                aPos.X() = Max( (long) 0, aPos.X() );
+                aPos.Y() = Max( (long) 0, aPos.Y() );
+                SetVisArea( aPos );
+            }
             aOpt.SetZoom    ( sal_uInt16(nFac) );
             aOpt.SetReadonly(pOpt->IsReadonly());
             pWrtShell->ApplyViewOptions( aOpt );
@@ -175,8 +237,9 @@ void SwView::_SetZoom( const Size &rEditSize, SvxZoomType eZoomType,
         {
             Point aPos;
 
-            if ( eZoomType == SVX_ZOOM_WHOLEPAGE )
+            if ( eZoomType == SVX_ZOOM_WHOLEPAGE ) {
                 aPos.Y() = pWrtShell->GetAnyCurRect(RECT_PAGE).Top() - DOCUMENTBORDER;
+            }
             else
             {
                 //sicherstellen, dass sich der Cursor im sichtbaren
diff --git a/sw/source/ui/uiview/viewport.cxx b/sw/source/ui/uiview/viewport.cxx
index d6b723d..bb99940 100644
--- a/sw/source/ui/uiview/viewport.cxx
+++ b/sw/source/ui/uiview/viewport.cxx
@@ -1307,13 +1307,17 @@ sal_Bool SwView::HandleWheelCommands( const CommandEvent& rCEvt )
     const CommandWheelData* pWData = rCEvt.GetWheelData();
     if( pWData && COMMAND_WHEEL_ZOOM == pWData->GetMode() )
     {
-        sal_uInt16 nFact = pWrtShell->GetViewOptions()->GetZoom();
+        bool bZoomIn = true;
+        long nFact = pWrtShell->GetViewOptions()->GetZoom();
         if( 0L > pWData->GetDelta() )
-            nFact = static_cast< sal_uInt16 >(Max( 20, basegfx::zoomtools::zoomOut( 
static_cast<int>(nFact) )));
+        {
+            bZoomIn = false;
+            nFact = Max( 20, basegfx::zoomtools::zoomOut( static_cast<int>(nFact) ));
+        }
         else
-            nFact = static_cast< sal_uInt16 >(Min( 600, basegfx::zoomtools::zoomIn( 
static_cast<int>(nFact) )));
+            nFact = Min( 600, basegfx::zoomtools::zoomIn( static_cast<int>(nFact) ));
 
-        SetZoom( SVX_ZOOM_PERCENT, nFact );
+        SetZoom( SVX_ZOOM_PERCENT, nFact, sal_False ,rCEvt.GetMousePosPixel(), bZoomIn);
         bOk = sal_True;
     }
     else
-- 
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.