/* ******************************************************************************
* 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.ui.gallery;
import static org.xmind.ui.gallery.NavigationViewer.BIG_ALPHA;
import static org.xmind.ui.gallery.NavigationViewer.BIG_HEIGHT;
import static org.xmind.ui.gallery.NavigationViewer.SMALL_ALPHA;
import static org.xmind.ui.gallery.NavigationViewer.SMALL_HEIGHT;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.xmind.gef.draw2d.graphics.GraphicsUtils;
/**
* @author Frank Shaka
*
*/
public class NavigationItemFigure extends Figure {
private class MaskBorder extends LineBorder {
/**
*
*/
public MaskBorder() {
super(ColorConstants.lightGray, 1);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Border#getInsets(org.eclipse.draw2d.IFigure)
*/
public Insets getInsets(IFigure figure) {
return NO_INSETS;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Border#paint(org.eclipse.draw2d.IFigure,
* org.eclipse.draw2d.Graphics, org.eclipse.draw2d.geometry.Insets)
*/
public void paint(IFigure figure, Graphics graphics, Insets insets) {
if (alpha > 0) {
tempRect.setBounds(getPaintRectangle(figure, insets));
graphics.setAlpha(alpha);
graphics.setBackgroundColor(ColorConstants.black);
graphics.fillRectangle(tempRect);
} else {
super.paint(figure, graphics, insets);
}
}
}
private static final double MIN_SCALE = ((double) SMALL_HEIGHT)
/ ((double) BIG_HEIGHT);
private static final double MAX_SCALE = 1;
private Image image = null;
private String text = null;
private double state = 0;
private int alpha = 0;
/**
*
*/
public NavigationItemFigure() {
setBorder(new MaskBorder());
setOpaque(true);
setBackgroundColor(ColorConstants.white);
updateState();
}
/**
* @return the image
*/
public Image getImage() {
return image;
}
/**
* @param image
* the image to set
*/
public void setImage(Image image) {
if (image == this.image)
return;
this.image = image;
repaint();
}
/**
* @return the text
*/
public String getText() {
return text;
}
/**
* @param text
* the text to set
*/
public void setText(String text) {
if (text == this.text || (text != null && text.equals(this.text)))
return;
this.text = text;
repaint();
}
/**
* @return the state
*/
public double getState() {
return state;
}
/**
* @param state
* the state to set
*/
public void setState(double state) {
if (state == this.state)
return;
this.state = state;
updateState();
revalidate();
}
private void updateState() {
int s = (int) seg(SMALL_HEIGHT, BIG_HEIGHT, state);
setPreferredSize(s, s);
alpha = (int) seg(SMALL_ALPHA, BIG_ALPHA, state);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Figure#paint(org.eclipse.draw2d.Graphics)
*/
@Override
public void paint(Graphics graphics) {
graphics.setAdvanced(true);
graphics.setAntialias(SWT.ON);
super.paint(graphics);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics)
*/
@Override
protected void paintFigure(Graphics graphics) {
super.paintFigure(graphics);
Rectangle b = getBounds();
float cx = b.x + ((float) b.width) / 2;
float cy = b.y + ((float) b.height) / 2;
double scale = seg(MIN_SCALE, MAX_SCALE, state);
Rectangle r = getClientArea(Rectangle.SINGLETON);
float x = r.x - ((float) BIG_HEIGHT - b.width) / 2 - cx;
float y = r.y - ((float) BIG_HEIGHT - b.height) / 2 - cy;
float w = r.width + (BIG_HEIGHT - b.width);
float h = r.height + (BIG_HEIGHT - b.height);
graphics.pushState();
try {
// Configure graphics:
graphics.translate(cx, cy);
graphics.scale(scale);
if (image != null) {
paintImage(graphics, x, y, w, h);
} else if (text != null) {
paintText(graphics, x, y, w, h);
}
} finally {
graphics.restoreState();
graphics.popState();
}
}
private void paintImage(Graphics graphics, float x, float y, float w,
float h) {
org.eclipse.swt.graphics.Rectangle ir = image.getBounds();
float iw = ir.width;
float ih = ir.height;
float tw = iw;
float th = ih;
if (tw > w) {
th = th * w / tw;
tw = w;
}
if (th > h) {
tw = tw * h / th;
th = h;
}
float tx = x + (w - tw) / 2;
float ty = y + (h - th) / 2;
graphics.drawImage(image, 0, 0, (int) iw, (int) ih, (int) tx, (int) ty,
(int) tw, (int) th);
}
private void paintText(Graphics graphics, float x, float y, float w, float h) {
float m = w * 0.05f;
x += m;
y += m;
w -= m + m;
h -= m + m;
Dimension s = GraphicsUtils.getAdvanced().getTextSize(text,
graphics.getFont());
float tw = s.width;
float th = s.height;
double ts = 1;
if (tw > w) {
th = th * w / tw;
ts = ts * w / tw;
tw = w;
}
if (th > h) {
tw = tw * h / th;
ts = ts * h / th;
th = h;
}
float tx = x + (w - tw) / 2;
float ty = y + (h - th) / 2;
if (ts == 1) {
graphics.drawText(text, (int) tx, (int) ty);
} else {
graphics.scale(ts);
graphics.drawText(text, (int) (tx / ts), (int) (ty / ts));
}
}
private static double seg(double min, double max, double ratio) {
return min + (max - min) * ratio;
}
}