package org.openscada.vi.ui.draw2d.impl;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LayeredPane;
import org.eclipse.draw2d.ScalableFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.geometry.Translatable;
import org.eclipse.swt.SWT;
/**
* A non-freeform, scalable layered pane.
*
* @author Eric Bordeau
* @author Jens Reimann
* @since 2.1.1
*/
public class ScalableLayeredPane extends LayeredPane implements ScalableFigure
{
private double scale = 1.0;
/**
* @see IFigure#getClientArea(Rectangle)
*/
@Override
public Rectangle getClientArea ( final Rectangle rect )
{
super.getClientArea ( rect );
// try to compensate scaling artifacts
final int dx = (int) ( rect.x / this.scale ) - ( rect.x = (int)Math.ceil ( rect.x / this.scale ) );
final int dy = (int) ( rect.y / this.scale ) - ( rect.y = (int)Math.ceil ( rect.y / this.scale ) );
rect.width = (int)Math.ceil ( rect.width / this.scale ) - dx;
rect.height = (int)Math.ceil ( rect.height / this.scale ) - dy;
/*
rect.x /= this.scale;
rect.y /= this.scale;
rect.width /= this.scale;
rect.height /= this.scale;
*/
return rect;
}
/**
* @see Figure#getPreferredSize(int, int)
*/
@Override
public Dimension getMinimumSize ( final int wHint, final int hHint )
{
final Dimension d = super.getMinimumSize ( wHint != SWT.DEFAULT ? (int) ( wHint / getScale () ) : SWT.DEFAULT, hHint != SWT.DEFAULT ? (int) ( hHint / getScale () ) : SWT.DEFAULT );
final int w = getInsets ().getWidth ();
final int h = getInsets ().getHeight ();
return d.getExpanded ( -w, -h ).scale ( this.scale ).expand ( w, h );
}
/**
* @see Figure#getPreferredSize(int, int)
*/
@Override
public Dimension getPreferredSize ( final int wHint, final int hHint )
{
final Dimension d = super.getPreferredSize ( wHint != SWT.DEFAULT ? (int) ( wHint / getScale () ) : SWT.DEFAULT, hHint != SWT.DEFAULT ? (int) ( hHint / getScale () ) : SWT.DEFAULT );
final int w = getInsets ().getWidth ();
final int h = getInsets ().getHeight ();
return d.getExpanded ( -w, -h ).scale ( this.scale ).expand ( w, h );
}
/**
* Returns the scale level, default is 1.0.
*
* @return the scale level
*/
@Override
public double getScale ()
{
return this.scale;
}
/**
* @see org.eclipse.draw2d.IFigure#isCoordinateSystem()
*/
@Override
public boolean isCoordinateSystem ()
{
return true;
}
/**
* @see org.eclipse.draw2d.Figure#paintClientArea(Graphics)
*/
@Override
protected void paintClientArea ( final Graphics graphics )
{
if ( getChildren ().isEmpty () )
{
return;
}
if ( this.scale == 1.0 )
{
super.paintClientArea ( graphics );
}
else
{
final ScaledGraphics g = new ScaledGraphics ( graphics );
final boolean optimizeClip = getBorder () == null || getBorder ().isOpaque ();
if ( !optimizeClip )
{
g.clipRect ( getBounds ().getCropped ( getInsets () ) );
}
g.scale ( this.scale );
g.pushState ();
paintChildren ( g );
g.dispose ();
graphics.restoreState ();
}
}
/**
* Sets the zoom level
*
* @param newZoom
* The new zoom level
*/
@Override
public void setScale ( final double newZoom )
{
if ( this.scale == newZoom )
{
return;
}
this.scale = newZoom;
fireMoved (); // for AncestorListener compatibility
revalidate ();
repaint ();
}
/**
* @see org.eclipse.draw2d.Figure#translateFromParent(Translatable)
*/
@Override
public void translateFromParent ( final Translatable t )
{
t.performScale ( 1 / this.scale );
}
/**
* @see org.eclipse.draw2d.Figure#translateToParent(Translatable)
*/
@Override
public void translateToParent ( final Translatable t )
{
t.performScale ( this.scale );
}
}