* <code>null</code>.
*/
private Rectangle calculateVisibleViewRect( final ZoomStateHolder aZoomState, final Point aCenterPoint )
{
SignalDiagramComponent signalDiagram = getSignalDiagram();
SignalDiagramModel model = getModel();
// Take the location of the signal diagram component, as it is the
// only one that is shifted in location by its (parent) scrollpane...
Point currentLocation = signalDiagram.getLocation();
Rectangle currentVisibleRect = signalDiagram.getVisibleRect();
int mx = ( aCenterPoint != null ) ? aCenterPoint.x : ( int )currentVisibleRect.getCenterX();
Rectangle visibleRect = new Rectangle();
// Calculate the relative factor we're using...
double relFactor = aZoomState.factor / getFactor();
// Calculate the new dimensions and the new location of the view...
switch ( aZoomState.lastAction )
{
case IN:
case OUT:
{
// Use the given (relative!) factor to calculate the new
// width of the view!
Dimension viewSize = signalDiagram.getPreferredSize();
visibleRect.width = ( int )( viewSize.width * relFactor );
visibleRect.height = currentVisibleRect.height;
// Recalculate the new screen position of the visible view
// rectangle; the X-coordinate shifts relative to the zoom
// factor, while the Y-coordinate remains as-is...
visibleRect.x = ( int )Math.round( currentLocation.x - ( mx * relFactor ) + mx );
visibleRect.y = currentLocation.y;
break;
}
case ALL:
{
// The new width of the view is always the same as the width of the view
// size...
Dimension outerViewSize = getOuterViewSize( signalDiagram, true, true );
visibleRect.width = outerViewSize.width;
visibleRect.height = outerViewSize.height;
// Since everything fits on screen, we can reset the view location to
// its initial X-coordinate...
visibleRect.x = 0;
visibleRect.y = currentLocation.y;
break;
}
case MAXIMUM:
case DEFAULT:
{
// Recalculate the new width based on the max./default zoom level...
visibleRect.width = ( int )( model.getAbsoluteLength() * aZoomState.factor );
visibleRect.height = currentVisibleRect.height;
// Recalculate the new screen position of the visible view
// rectangle; the X-coordinate shifts relative to the zoom
// factor, while the Y-coordinate remains as-is...
visibleRect.x = ( int )Math.round( currentLocation.x - ( mx * relFactor ) + mx );
visibleRect.y = currentLocation.y;
break;
}
case RESTORE:
default:
{
// Recalculate the new width based on the old zoom level...
visibleRect.width = ( int )( model.getAbsoluteLength() * aZoomState.factor );
visibleRect.height = currentVisibleRect.height;
// Keep the location as-is...
visibleRect.x = currentLocation.x;
visibleRect.y = currentLocation.y;
break;
}
}
// Ensure the visible location stays in the calculated minimum and
// maximum...
int maxX = ( visibleRect.width - currentVisibleRect.width );
if ( Math.abs( visibleRect.x ) > maxX )
{
visibleRect.x = -maxX;
}
// View locations appear to be always negative with respect to the (0,
// 0)-coordinate...
if ( visibleRect.x > 0 )
{
visibleRect.x = -visibleRect.x;
}
// Ensure the minimum height of the view is adhered...
int minimumHeight = model.getMinimumHeight();
if ( visibleRect.height < minimumHeight )
{
visibleRect.height = minimumHeight;
}
// Try to suppress the vertical scrollbar, if possible...