/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.gef.draw2d;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Image;
import org.xmind.gef.draw2d.geometry.Geometry;
import org.xmind.gef.draw2d.geometry.PrecisionDimension;
import org.xmind.gef.draw2d.geometry.PrecisionRectangle;
import org.xmind.gef.draw2d.geometry.PrecisionRotator;
/**
* @author Frank Shaka
*/
public class RotatableSizeableImageFigure extends SizeableImageFigure implements
IRotatableFigure {
private PrecisionRotator rotator = new PrecisionRotator();
private PrecisionDimension normalPrefSize = null;
private Dimension rotatedPrefSize = null;
public RotatableSizeableImageFigure() {
}
public RotatableSizeableImageFigure(Image image) {
super(image);
}
public PrecisionDimension getNormalPreferredSize(int wHint, int hHint) {
if (normalPrefSize == null) {
normalPrefSize = new PrecisionDimension(super.getPreferredSize(
wHint, hHint));
}
return normalPrefSize;
}
public Dimension getPreferredSize(int wHint, int hHint) {
if (rotatedPrefSize == null) {
rotatedPrefSize = rotator.td(getNormalPreferredSize(wHint, hHint))
.toDraw2DDimension();
}
return rotatedPrefSize;
}
public void invalidate() {
super.invalidate();
normalPrefSize = null;
rotatedPrefSize = null;
}
public double getRotationDegrees() {
return rotator.getAngle();
}
public void setRotationDegrees(double angle) {
double oldAngle = getRotationDegrees();
if (Math.abs(oldAngle - angle) < 0.00000001d)
return;
rotator.setAngle(angle);
revalidate();
repaint();
}
private boolean isRotated() {
return !Geometry.isSameAngleDegree(getRotationDegrees(), 0, 0.0000001);
}
protected void paintImage(Graphics graphics, Image image,
Dimension imageSize, Rectangle clientArea) {
if (!isRotated()) {
super.paintImage(graphics, image, imageSize, clientArea);
return;
}
// Dimension realClientSize = rotator.a(clientArea.getSize(),
// imageSize.width, -1);
Point center = clientArea.getCenter();
rotator.setOrigin(center.x, center.y);
PrecisionRectangle r = rotator.r(new PrecisionRectangle(clientArea),
imageSize.width, -1).translate(-center.x, -center.y);
// Rectangle realClientArea = new Rectangle();
// realClientArea.setSize(realClientSize);
// Dimension delta = realClientSize.getScaled(0.5);
// realClientArea.translate(-delta.width, -delta.height);
graphics.pushState();
try {
graphics.translate(center.x, center.y);
graphics.rotate((float) getRotationDegrees());
super.paintImage(graphics, image, imageSize, r.toDraw2DRectangle());
graphics.translate(-center.x, -center.y);
} finally {
graphics.popState();
graphics.restoreState();
}
}
}