/*
* $Id$
*
* Copyright (c) 2000-2003 by Rodney Kinney
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License (LGPL) as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, copies are available
* at http://www.opensource.org.
*/
package VASSAL.counters;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
import java.util.List;
public class ColoredBorder implements Highlighter {
protected Color c;
protected int thickness;
// Additional Highlighters
protected List<Highlighter> highlighters = new ArrayList<Highlighter>();
public ColoredBorder() {
this(Color.black, 3);
}
public ColoredBorder(Color c, int thickness) {
this.c = c;
this.thickness = thickness;
}
public void addHighlighter(Highlighter h) {
highlighters.add(h);
}
public void removeHighlighter(Highlighter h) {
highlighters.remove(h);
}
public void draw(GamePiece p, Graphics g, int x, int y,
Component obs, double zoom) {
if (thickness > 0) {
if (c != null) {
// Find the border by outsetting the bounding box, and then scaling
// the shape to fill the outset.
final Shape s = p.getShape();
final Rectangle br = s.getBounds();
// Don't bother if the shape is empty.
if (!br.isEmpty()) {
final double xzoom = (br.getWidth()+1) / br.getWidth();
final double yzoom = (br.getHeight()+1) / br.getHeight();
final AffineTransform t = AffineTransform.getTranslateInstance(x,y);
t.scale(xzoom*zoom, yzoom*zoom);
final Graphics2D g2d = (Graphics2D) g;
final Stroke str = g2d.getStroke();
g2d.setStroke(
new BasicStroke(Math.max(1, Math.round(zoom*thickness))));
g2d.setColor(c);
g2d.draw(t.createTransformedShape(s));
g2d.setStroke(str);
}
}
else {
highlightSelectionBounds(p, g, x, y, obs, zoom);
}
}
// Draw any additional highlighters
for (Highlighter h : highlighters) {
h.draw(p, g, x, y, obs, zoom);
}
}
protected void highlightSelectionBounds(GamePiece p, Graphics g, int x, int y, Component obs, double zoom) {
Rectangle r = p.getShape().getBounds();
g.setColor(c);
for (int i = 1; i < thickness; ++i)
g.drawRect(x + (int) (zoom * r.x) - i,
y + (int) (zoom * r.y) - i,
(int) (zoom * r.width) + 2 * i - 1,
(int) (zoom * r.height) + 2 * i - 1);
}
public Rectangle boundingBox(GamePiece p) {
final Rectangle r = p.getShape().getBounds();
r.translate(-thickness, -thickness);
r.setSize(r.width + 2 * thickness, r.height + 2 * thickness);
for (Highlighter h : highlighters) r.add(h.boundingBox(p));
return r;
}
public void setColor(Color c) {
this.c = c;
}
public Color getColor() {
return c;
}
public int getThickness() {
return thickness;
}
public void setThickness(int thickness) {
this.thickness = thickness;
}
}