diff options
author | Noel Power <noel.power@suse.com> | 2012-11-27 17:56:33 +0000 |
---|---|---|
committer | Noel Power <noel.power@suse.com> | 2012-11-28 14:50:25 +0000 |
commit | c4e649f0cd013e86adbd794859bcc3cb9ee3aa61 (patch) | |
tree | 41038de6c78c01a15e730d218ea5a61a28de8fdd /sc/source/ui/drawfunc | |
parent | Updated core (diff) | |
download | core-c4e649f0cd013e86adbd794859bcc3cb9ee3aa61.tar.gz core-c4e649f0cd013e86adbd794859bcc3cb9ee3aa61.zip |
Sync draw object to calc grid for better alignment when zooming
There can be some serious rounding errors involved when calculating where to
draw the grid lines for the various row heights in a document. This can be
especially true for a document that has many different row heights.
This results in draw objects appearing to move relative to the grid line at
different zoom levels. This patch attempts to fix this problem adjusting
the position of the shapes as they are drawn to ensure their position
relative to grid appears to be stable. We do this by translating the position
of the shape to the corrosponding position of it's cell anchor. Of course not
all shapes are cell anchored and in this case we position the shape relative
a temporary synthesized cell anchor.
The patch essentially does the following
a) calculates the offset to be applied for each shape at the current zoom level
to ensure that the shape will be drawn relative to the correct cell grid
see drwlayer.cxx, drawview.cxx & gridwin3.cxx, svdobj.[ch]xx
b) apply the offset in the drawing layer for each of the different drawing
primitives see svx/source/sdr/contact/*
c) making sure the position and size of the newly created shape ( at any zoom
level ) are still as expected when zoom level is changed.
see. sc/source/ui/drawfunc/fuco*.cxx &
d) making sure that overlays and handles are displayed at the correct position
see svx/source/svdraw/*
it could also be that a full blown transform might be needed to additionally
scale the object ( to ensure that the edges of the object stay stable relative
to ajacent grid lines ) If necessary we could do that in a later step.
Change-Id: I02232f8ba192d58dbf96b80adf66c281cd0f65e8
Diffstat (limited to 'sc/source/ui/drawfunc')
-rw-r--r-- | sc/source/ui/drawfunc/fuconarc.cxx | 6 | ||||
-rw-r--r-- | sc/source/ui/drawfunc/fuconcustomshape.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/drawfunc/fuconrec.cxx | 8 | ||||
-rw-r--r-- | sc/source/ui/drawfunc/fuconstr.cxx | 41 | ||||
-rw-r--r-- | sc/source/ui/drawfunc/fuconuno.cxx | 7 | ||||
-rw-r--r-- | sc/source/ui/drawfunc/futext.cxx | 21 |
6 files changed, 85 insertions, 5 deletions
diff --git a/sc/source/ui/drawfunc/fuconarc.cxx b/sc/source/ui/drawfunc/fuconarc.cxx index a0b2bed7110d..e7507b6e6703 100644 --- a/sc/source/ui/drawfunc/fuconarc.cxx +++ b/sc/source/ui/drawfunc/fuconarc.cxx @@ -74,8 +74,14 @@ sal_Bool FuConstArc::MouseButtonDown( const MouseEvent& rMEvt ) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPnt ); pWindow->CaptureMouse(); pView->BegCreateObj( aPnt ); + pView->GetCreateObj()->SetGridOffset( aGridOff ); bReturn = sal_True; } return bReturn; diff --git a/sc/source/ui/drawfunc/fuconcustomshape.cxx b/sc/source/ui/drawfunc/fuconcustomshape.cxx index 80322d1948db..532a803ea093 100644 --- a/sc/source/ui/drawfunc/fuconcustomshape.cxx +++ b/sc/source/ui/drawfunc/fuconcustomshape.cxx @@ -83,6 +83,12 @@ sal_Bool FuConstCustomShape::MouseButtonDown(const MouseEvent& rMEvt) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPnt ); + pWindow->CaptureMouse(); pView->BegCreateObj(aPnt); @@ -95,6 +101,7 @@ sal_Bool FuConstCustomShape::MouseButtonDown(const MouseEvent& rMEvt) bForceNoFillStyle = sal_True; if ( bForceNoFillStyle ) pObj->SetMergedItem( XFillStyleItem( XFILL_NONE ) ); + pObj->SetGridOffset( aGridOff ); } bReturn = sal_True; diff --git a/sc/source/ui/drawfunc/fuconrec.cxx b/sc/source/ui/drawfunc/fuconrec.cxx index 8ef1ce7ab1ef..9a77e4e9d343 100644 --- a/sc/source/ui/drawfunc/fuconrec.cxx +++ b/sc/source/ui/drawfunc/fuconrec.cxx @@ -82,7 +82,11 @@ sal_Bool FuConstRectangle::MouseButtonDown(const MouseEvent& rMEvt) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPos( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); - + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPos ); pWindow->CaptureMouse(); if ( pView->GetCurrentObjIdentifier() == OBJ_CAPTION ) @@ -95,6 +99,8 @@ sal_Bool FuConstRectangle::MouseButtonDown(const MouseEvent& rMEvt) } else bReturn = pView->BegCreateObj(aPos); + if ( bReturn ) + pView->GetCreateObj()->SetGridOffset( aGridOff ); } return bReturn; } diff --git a/sc/source/ui/drawfunc/fuconstr.cxx b/sc/source/ui/drawfunc/fuconstr.cxx index e7786de03d8a..320b70182ad5 100644 --- a/sc/source/ui/drawfunc/fuconstr.cxx +++ b/sc/source/ui/drawfunc/fuconstr.cxx @@ -39,6 +39,8 @@ #include "futext.hxx" #include "sc.hrc" #include "drawview.hxx" +#include "document.hxx" +#include "gridwin.hxx" // Maximal erlaubte Mausbewegung um noch Drag&Drop zu starten //! fusel,fuconstr,futext - zusammenfassen! @@ -75,6 +77,39 @@ sal_uInt8 FuConstruct::Command(const CommandEvent& rCEvt) return FuDraw::Command( rCEvt ); } +// Calculate and return offset at current zoom. rInOutPos is adjusted by +// the calculated offset. rInOutPos now points to the position than when +// scaled to 100% actually would be at the position you see at the current zoom +// ( relative to the grid ) note: units are expected to be in 100th mm +Point FuConstruct::CurrentGridSyncOffsetAndPos( Point& rInOutPos ) +{ + Point aRetGridOff; + ScViewData* pViewData = pViewShell->GetViewData(); + ScDocument* pDoc = pViewData ? pViewData->GetDocument() : NULL; + if ( pViewData && pDoc ) + { + // rInOutPos mightn't be where you think it is if there is zoom + // involved. Lets calculate where aPos would be at 100% zoom + // that's the actual correct position for the object ( when you + // restore the zoom. + Rectangle aObjRect( rInOutPos, rInOutPos ); + ScRange aRange = pDoc->GetRange( pView->GetTab(), aObjRect ); + ScAddress aOldStt = aRange.aStart; + Point aOldPos( pDoc->GetColOffset( aOldStt.Col(), aOldStt.Tab() ), pDoc->GetRowOffset( aOldStt.Row(), aOldStt.Tab() ) ); + aOldPos.X() = sc::TwipsToHMM( aOldPos.X() ); + aOldPos.Y() = sc::TwipsToHMM( aOldPos.Y() ); + ScSplitPos eWhich = pViewData->GetActivePart(); + ScGridWindow* pGridWin = (ScGridWindow*)pViewData->GetActiveWin(); + // and equiv screen pos + Point aScreenPos = pViewShell->GetViewData()->GetScrPos( aOldStt.Col(), aOldStt.Row(), eWhich, sal_True ); + MapMode aDrawMode = pGridWin->GetDrawMapMode(); + Point aCurPosHmm = pGridWin->PixelToLogic(aScreenPos, aDrawMode ); + Point aOff = ( rInOutPos - aCurPosHmm ); + rInOutPos = aOldPos + aOff; + aRetGridOff = aCurPosHmm - aOldPos; + } + return aRetGridOff; +} /************************************************************************* |* |* MouseButtonDown-event @@ -144,6 +179,12 @@ sal_Bool FuConstruct::MouseMove(const MouseEvent& rMEvt) Point aPix(rMEvt.GetPosPixel()); Point aPnt( pWindow->PixelToLogic(aPix) ); + // if object is being created then more than likely the mouse + // position has been 'adjusted' for the current zoom, need to + // restore the mouse position here to ensure resize works as expected + if ( pView->GetCreateObj() ) + aPnt -= pView->GetCreateObj()->GetGridOffset(); + if ( pView->IsAction() ) { ForceScroll(aPix); diff --git a/sc/source/ui/drawfunc/fuconuno.cxx b/sc/source/ui/drawfunc/fuconuno.cxx index 924ab3e60aad..ba0e4b71613a 100644 --- a/sc/source/ui/drawfunc/fuconuno.cxx +++ b/sc/source/ui/drawfunc/fuconuno.cxx @@ -76,8 +76,15 @@ sal_Bool FuConstUnoControl::MouseButtonDown(const MouseEvent& rMEvt) if ( rMEvt.IsLeft() && !pView->IsAction() ) { Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aPnt ); + pWindow->CaptureMouse(); pView->BegCreateObj(aPnt); + pView->GetCreateObj()->SetGridOffset( aGridOff ); bReturn = sal_True; } return bReturn; diff --git a/sc/source/ui/drawfunc/futext.cxx b/sc/source/ui/drawfunc/futext.cxx index 2505ada36399..f014ad29f169 100644 --- a/sc/source/ui/drawfunc/futext.cxx +++ b/sc/source/ui/drawfunc/futext.cxx @@ -314,7 +314,15 @@ sal_Bool FuText::MouseButtonDown(const MouseEvent& rMEvt) /********************************************************** * Objekt erzeugen **********************************************************/ - pView->BegCreateObj(aMDPos, (OutputDevice*) NULL); + // Hack to align object to nearest grid position where object + // would be anchored ( if it were cell anchored ) + // Get grid offset for current position ( note: aPnt is + // also adjusted ) + Point aGridOff = CurrentGridSyncOffsetAndPos( aMDPos ); + + bool bRet = pView->BegCreateObj(aMDPos, (OutputDevice*) NULL); + if ( bRet ) + pView->GetCreateObj()->SetGridOffset( aGridOff ); } } } @@ -359,14 +367,19 @@ sal_Bool FuText::MouseMove(const MouseEvent& rMEvt) aDragTimer.Stop(); } + Point aPix(rMEvt.GetPosPixel()); + Point aPnt(pWindow->PixelToLogic(aPix)); + // if object is being created then more than likely the mouse + // position has been 'adjusted' for the current zoom, need to + // restore the mouse position here to ensure resize works as expected + if ( pView->GetCreateObj() ) + aPnt -= pView->GetCreateObj()->GetGridOffset(); + if ( pView->MouseMove(rMEvt, pWindow) ) return (sal_True); // Event von der SdrView ausgewertet if ( pView->IsAction() ) { - Point aPix(rMEvt.GetPosPixel()); - Point aPnt(pWindow->PixelToLogic(aPix)); - ForceScroll(aPix); pView->MovAction(aPnt); } |