Index: mitk/Core/Code/DataManagement/mitkDisplayGeometry.cpp =================================================================== --- mitk/Core/Code/DataManagement/mitkDisplayGeometry.cpp (revision 24525) +++ mitk/Core/Code/DataManagement/mitkDisplayGeometry.cpp (working copy) @@ -190,7 +190,6 @@ if ( SetScaleFactor(m_ScaleFactorMMPerDisplayUnit/factor) ) { - // only correct origin if zooming was ok return SetOriginInMM(m_OriginInMM-centerInDisplayUnits.GetVectorFromOrigin()*(1-factor)*m_ScaleFactorMMPerDisplayUnit); } else @@ -199,6 +198,16 @@ } } +bool mitk::DisplayGeometry::ZoomWithFixFocus(ScalarType factor, const Point2D& focusDisplayUnits, const Point2D& focusUnitsInMM ) +{ + assert(factor > 0); + + SetScaleFactor(m_ScaleFactorMMPerDisplayUnit/factor); + SetOriginInMM(focusUnitsInMM.GetVectorFromOrigin()-focusDisplayUnits.GetVectorFromOrigin()*m_ScaleFactorMMPerDisplayUnit); + return true; +} + + bool mitk::DisplayGeometry::MoveBy(const Vector2D& shiftInDisplayUnits) { SetOriginInMM(m_OriginInMM+shiftInDisplayUnits*m_ScaleFactorMMPerDisplayUnit); @@ -452,14 +461,22 @@ bool zoomYtooBig = displayHeightPx * m_ScaleFactorMMPerDisplayUnit < m_MinWorldViewPercentage * worldHeightMM; // constrain zooming in in x direction - if ( zoomXtooBig ) + if ( zoomXtooBig && zoomYtooBig) + { + double fx = worldWidthMM * m_MinWorldViewPercentage / displayWidthPx; + double fy = worldHeightMM * m_MinWorldViewPercentage / displayHeightPx; + newScaleFactor = fx < fy ? fx : fy; + correctZooming = true; + } + + else if ( zoomXtooBig ) { newScaleFactor = worldWidthMM * m_MinWorldViewPercentage / displayWidthPx; correctZooming = true; } // constrain zooming in in y direction - if ( zoomYtooBig ) + else if ( zoomYtooBig ) { newScaleFactor = worldHeightMM * m_MinWorldViewPercentage / displayHeightPx; correctZooming = true; @@ -497,7 +514,7 @@ // // In both situations we center the not-maxed out direction // - if ( zoomXtooSmall && zoomYtooSmall ) +if ( zoomXtooSmall && zoomYtooSmall ) { // determine and set the bigger scale factor float fx = worldWidthMM * m_MaxWorldViewPercentage / displayWidthPx; @@ -507,8 +524,18 @@ correctZooming = true; } + + // actually execute correction + if (correctZooming) + { + SetScaleFactor(newScaleFactor); + } + + displayWidthMM = m_SizeInDisplayUnits[0] * m_ScaleFactorMMPerDisplayUnit; + displayHeightMM = m_SizeInDisplayUnits[1] * m_ScaleFactorMMPerDisplayUnit; + // constrain panning - if (zoomXtooSmall) + if(worldWidthMM center x @@ -524,8 +551,7 @@ correctPanning = true; } // make sure right display border inside our world - else - if (displayXMM + displayWidthMM > worldWidthMM) + else if (displayXMM + displayWidthMM > worldWidthMM) { newOrigin[0] = worldWidthMM - displayWidthMM; correctPanning = true; @@ -533,7 +559,7 @@ } - if (zoomYtooSmall) + if (worldHeightMM center y @@ -542,28 +568,24 @@ } else { - // make sure bottom display border inside our world - if (displayYMM < 0) + // make sure top display border inside our world + if (displayYMM + displayHeightMM > worldHeightMM) { - newOrigin[1] = 0; + newOrigin[1] = worldHeightMM - displayHeightMM; correctPanning = true; } - // make sure top display border inside our world + // make sure bottom display border inside our world else - if (displayYMM + displayHeightMM > worldHeightMM) + if (displayYMM < 0) { - newOrigin[1] = worldHeightMM - displayHeightMM; + newOrigin[1] = 0; correctPanning = true; } - } - // actually execute correction - if (correctZooming) - { - SetScaleFactor(newScaleFactor); } - if (correctPanning) + + if (correctPanning) { SetOriginInMM( newOrigin ); } Index: mitk/Core/Code/DataManagement/mitkDisplayGeometry.h =================================================================== --- mitk/Core/Code/DataManagement/mitkDisplayGeometry.h (revision 24525) +++ mitk/Core/Code/DataManagement/mitkDisplayGeometry.h (working copy) @@ -136,6 +136,10 @@ // \return true if zoom request was within accepted limits virtual bool Zoom(ScalarType factor, const Point2D& centerInDisplayUnits); + + // \return true if zoom request was within accepted limits + virtual bool ZoomWithFixFocus(ScalarType factor, const Point2D& focusDisplayUnits, const Point2D& focusUnitsInMM ); + // \return true if move request was within accepted limits virtual bool MoveBy(const Vector2D& shiftInDisplayUnits); Index: mitk/Core/Code/Interactions/mitkDisplayCoordinateOperation.cpp =================================================================== --- mitk/Core/Code/Interactions/mitkDisplayCoordinateOperation.cpp (revision 24525) +++ mitk/Core/Code/Interactions/mitkDisplayCoordinateOperation.cpp (working copy) @@ -33,6 +33,22 @@ { } +mitk::DisplayCoordinateOperation::DisplayCoordinateOperation(mitk::OperationType operationType, + mitk::BaseRenderer* renderer, + const mitk::Point2D& startDisplayCoordinate, + const mitk::Point2D& lastDisplayCoordinate, + const mitk::Point2D& currentDisplayCoordinate, + const mitk::Point2D& startCoordinateInMM +) + : mitk::Operation(operationType), + m_Renderer(renderer), + m_StartDisplayCoordinate(startDisplayCoordinate), + m_LastDisplayCoordinate(lastDisplayCoordinate), + m_CurrentDisplayCoordinate(currentDisplayCoordinate), + m_StartCoordinateInMM(startCoordinateInMM) +{ +} + mitk::DisplayCoordinateOperation::~DisplayCoordinateOperation() { Index: mitk/Core/Code/Interactions/mitkDisplayVectorInteractor.h =================================================================== --- mitk/Core/Code/Interactions/mitkDisplayVectorInteractor.h (revision 24525) +++ mitk/Core/Code/Interactions/mitkDisplayVectorInteractor.h (working copy) @@ -66,6 +66,7 @@ mitk::Point2D m_StartDisplayCoordinate; mitk::Point2D m_LastDisplayCoordinate; mitk::Point2D m_CurrentDisplayCoordinate; + mitk::Point2D m_StartCoordinateInMM; OperationActor* m_Destination; }; Index: mitk/Core/Code/Interactions/mitkDisplayCoordinateOperation.h =================================================================== --- mitk/Core/Code/Interactions/mitkDisplayCoordinateOperation.h (revision 24525) +++ mitk/Core/Code/Interactions/mitkDisplayCoordinateOperation.h (working copy) @@ -46,6 +46,14 @@ const mitk::Point2D& currentDisplayCoordinate ); +DisplayCoordinateOperation(mitk::OperationType operationType, + mitk::BaseRenderer* renderer, + const mitk::Point2D& startDisplayCoordinate, + const mitk::Point2D& lastDisplayCoordinate, + const mitk::Point2D& currentDisplayCoordinate, + const mitk::Point2D& startCoordinateInMM + ); + virtual ~DisplayCoordinateOperation(); mitk::BaseRenderer* GetRenderer(); @@ -53,6 +61,7 @@ mitkGetMacro(StartDisplayCoordinate, mitk::Point2D); mitkGetMacro(LastDisplayCoordinate, mitk::Point2D); mitkGetMacro(CurrentDisplayCoordinate, mitk::Point2D); + mitkGetMacro(StartCoordinateInMM, mitk::Point2D); mitk::Vector2D GetLastToCurrentDisplayVector(); mitk::Vector2D GetStartToCurrentDisplayVector(); @@ -65,6 +74,7 @@ const mitk::Point2D m_StartDisplayCoordinate; const mitk::Point2D m_LastDisplayCoordinate; const mitk::Point2D m_CurrentDisplayCoordinate; + const mitk::Point2D m_StartCoordinateInMM; }; } Index: mitk/Core/Code/Interactions/mitkDisplayVectorInteractor.cpp =================================================================== --- mitk/Core/Code/Interactions/mitkDisplayVectorInteractor.cpp (revision 24525) +++ mitk/Core/Code/Interactions/mitkDisplayVectorInteractor.cpp (working copy) @@ -90,9 +90,14 @@ case AcINITMOVE: { m_Sender=posEvent->GetSender(); + + mitk::Vector2D origin = m_Sender->GetDisplayGeometry()->GetOriginInMM(); + double scaleFactorMMPerDisplayUnit = m_Sender->GetDisplayGeometry()->GetScaleFactorMMPerDisplayUnit(); + m_StartDisplayCoordinate=posEvent->GetDisplayPosition(); m_LastDisplayCoordinate=posEvent->GetDisplayPosition(); m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition(); + m_StartCoordinateInMM=mitk::Point2D( ( origin+m_StartDisplayCoordinate.GetVectorFromOrigin()*scaleFactorMMPerDisplayUnit ).GetDataPointer() ); ok = true; break; } @@ -123,7 +128,7 @@ } case AcZOOM: { - DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpZOOM, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, posEvent->GetDisplayPosition()); + DisplayCoordinateOperation* doOp = new DisplayCoordinateOperation(OpZOOM, m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, posEvent->GetDisplayPosition(),m_StartCoordinateInMM); if (m_UndoEnabled) //write to UndoMechanism { Index: mitk/Core/Code/Interactions/mitkDisplayInteractor.cpp =================================================================== --- mitk/Core/Code/Interactions/mitkDisplayInteractor.cpp (revision 24525) +++ mitk/Core/Code/Interactions/mitkDisplayInteractor.cpp (working copy) @@ -76,7 +76,7 @@ // nothing to do, factor remains 1.0 } - renderer->GetDisplayGeometry()->Zoom(factor, dcOperation->GetStartDisplayCoordinate()); + renderer->GetDisplayGeometry()->ZoomWithFixFocus(factor, dcOperation->GetStartDisplayCoordinate(), dcOperation->GetStartCoordinateInMM()); mitk::RenderingManager::GetInstance()->RequestUpdate(renderer->GetRenderWindow()); ok = true;