/*
* $Id$
*
* Copyright (c) 2005 by Rodney Kinney, Brent Easton
*
* 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.build.module.gamepieceimage;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import javax.swing.KeyStroke;
import VASSAL.build.AutoConfigurable;
import VASSAL.configure.Configurer;
import VASSAL.configure.ConfigurerFactory;
import VASSAL.configure.FormattedStringConfigurer;
import VASSAL.configure.StringEnum;
import VASSAL.configure.VisibilityCondition;
import VASSAL.tools.ArrayUtils;
import VASSAL.tools.SequenceEncoder;
public class TextItem extends Item {
public static final String TYPE = "Text"; //$NON-NLS-1$
protected static final String FONT = "font"; //$NON-NLS-1$
protected static final String SOURCE = "source"; //$NON-NLS-1$
protected static final String TEXT = "text"; //$NON-NLS-1$
protected static final String LEFT = "left"; //$NON-NLS-1$
protected static final String CENTER = "center"; //$NON-NLS-1$
protected static final String RIGHT = "right"; //$NON-NLS-1$
protected static final String TOP = "top"; //$NON-NLS-1$
protected static final String BOTTOM = "bottom"; //$NON-NLS-1$
public static final String SRC_VARIABLE = "Specified in individual images"; //$NON-NLS-1$
public static final String SRC_FIXED = "Fixed for this layout"; //$NON-NLS-1$
protected static final String PIECE_NAME = "pieceName"; //$NON-NLS-1$
protected static final String LABEL = "label"; //$NON-NLS-1$
protected static final String DEFAULT_FORMAT = "$"+PIECE_NAME+"$"; //$NON-NLS-1$ //$NON-NLS-2$
public static final int AL_CENTER = 0;
public static final int AL_RIGHT = 1;
public static final int AL_LEFT = 2;
public static final int AL_TOP = 3;
public static final int AL_BOTTOM = 4;
protected String fontStyleName = "Default"; //$NON-NLS-1$
protected String textSource = SRC_VARIABLE;
protected String text = ""; //$NON-NLS-1$
protected String changeCmd = ""; //$NON-NLS-1$
protected KeyStroke changeKey;
protected boolean lockable = false;
protected String lockCmd = ""; //$NON-NLS-1$
protected KeyStroke lockKey;
public TextItem() {
super();
}
public TextItem(GamePieceLayout l) {
super(l);
}
public TextItem(GamePieceLayout l, String nam) {
this(l);
setConfigureName(nam);
}
public String[] getAttributeDescriptions() {
return ArrayUtils.insert(
super.getAttributeDescriptions(), 2,
"Font style: ",
"Text is: ",
"Text: "
);
}
public Class<?>[] getAttributeTypes() {
return ArrayUtils.insert(
super.getAttributeTypes(), 2,
new Class<?>[] {
FontStyleConfig.class,
TextSource.class,
String.class
}
);
}
public String[] getAttributeNames() {
return ArrayUtils.insert(
super.getAttributeNames(), 2,
new String[] {
FONT,
SOURCE,
TEXT
}
);
}
public static class FontStyleConfig implements ConfigurerFactory {
public Configurer getConfigurer(AutoConfigurable c, String key, String name) {
return new StringEnumConfigurer(key, name, FontManager.getFontManager().getFontNames());
}
}
public void setAttribute(String key, Object o) {
if (FONT.equals(key)) {
fontStyleName = (String)o;
}
else if (SOURCE.equals(key)) {
textSource = (String) o;
}
else if (TEXT.equals(key)) {
text = (String) o;
}
else {
super.setAttribute(key, o);
}
if (layout != null) {
layout.refresh();
}
}
public String getAttributeValueString(String key) {
if (FONT.equals(key)) {
return fontStyleName;
}
else if (SOURCE.equals(key)) {
return textSource + ""; //$NON-NLS-1$
}
else if (TEXT.equals(key)) {
return text;
}
else {
return super.getAttributeValueString(key);
}
}
public VisibilityCondition getAttributeVisibility(String name) {
if (TEXT.equals(name)) {
return fixedCond;
}
else {
return super.getAttributeVisibility(name);
}
}
private VisibilityCondition fixedCond = new VisibilityCondition() {
public boolean shouldBeVisible() {
return textSource.equals(SRC_FIXED);
}
};
public void draw(Graphics g, GamePieceImage defn) {
TextItemInstance ti = null;
FontStyle fs = FontManager.getFontManager().getFontStyle(fontStyleName);
Font f = fs.getFont();
if (defn != null) {
ti = defn.getTextInstance(name);
}
else {
defn = new GamePieceImage(getLayout());
ti = defn.getTextInstance(name);
}
if (ti == null) {
ti = new TextItemInstance();
}
Color fg = ti.getFgColor().getColor();
Color bg = ti.getBgColor().getColor();
if (fg == null && bg == null) {
return;
}
boolean outline = ti.isOutline();
Color ol = ti.getOutlineColor().getColor();
String compass = GamePieceLayout.getCompassPoint(getLocation());
int hAlign = AL_CENTER;
switch (compass.charAt(compass.length()-1)) {
case 'W':
hAlign = AL_LEFT;
break;
case 'E':
hAlign = AL_RIGHT;
}
int vAlign = AL_CENTER;
switch (compass.charAt(0)) {
case 'N':
vAlign = AL_TOP;
break;
case 'S':
vAlign = AL_BOTTOM;
}
Point origin = layout.getPosition(this);
String s = null;
if (textSource.equals(SRC_FIXED)) {
s = text;
}
else {
if (defn != null) {
if (ti != null) {
s = ti.getValue();
}
}
}
Graphics2D g2d = ((Graphics2D) g);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, isAntialias() ?
RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
AffineTransform saveXForm = null;
if (getRotation() != 0) {
saveXForm = g2d.getTransform();
AffineTransform newXForm =
AffineTransform.getRotateInstance(Math.toRadians(getRotation()), getLayout().getVisualizerWidth()/2, getLayout().getVisualizerHeight()/2);
g2d.transform(newXForm);
}
drawLabel(g, s, origin.x, origin.y, f, hAlign, vAlign, fg, bg, null, outline, ol);
if (saveXForm != null) {
g2d.setTransform(saveXForm);
}
}
public String getType() {
return TYPE;
}
public String getDisplayName() {
return "Label";
}
public Dimension getSize() {
return new Dimension(0,0);
}
public static Item decode(GamePieceLayout l, String s) {
TextItem item = new TextItem(l);
decode(item, s);
return item;
}
public static void decode(TextItem item, String s) {
SequenceEncoder.Decoder sd = new SequenceEncoder.Decoder(s, ';');
sd.nextToken();
item.fontStyleName = sd.nextToken(FontManager.DEFAULT);
if (item.fontStyleName.length() == 0) {
item.fontStyleName = FontManager.DEFAULT;
}
item.textSource = sd.nextToken(SRC_VARIABLE);
item.text = sd.nextToken(""); //$NON-NLS-1$
item.changeCmd = sd.nextToken(""); //$NON-NLS-1$
item.changeKey = sd.nextKeyStroke(null);
item.lockCmd = sd.nextToken(""); //$NON-NLS-1$
item.lockKey = sd.nextKeyStroke(null);
item.lockable = sd.nextBoolean(false);
}
public String encode() {
SequenceEncoder se1 = new SequenceEncoder(TextItem.TYPE, ';');
se1.append(fontStyleName == null ? "" : fontStyleName); //$NON-NLS-1$
se1.append(textSource);
se1.append(text);
se1.append(changeCmd);
se1.append(changeKey);
se1.append(lockCmd);
se1.append(lockKey);
se1.append(lockable);
SequenceEncoder se2 = new SequenceEncoder(se1.getValue(), '|');
se2.append(super.encode());
return se2.getValue();
}
public boolean isOutline() {
return FontManager.getFontManager().getFontStyle(fontStyleName).isOutline();
}
public boolean isFixed() {
return textSource.equals(SRC_FIXED);
}
public static class TextSource extends StringEnum {
public String[] getValidValues(AutoConfigurable target) {
return new String[] { SRC_VARIABLE, SRC_FIXED };
}
}
public static class NameFormatConfig implements ConfigurerFactory {
public Configurer getConfigurer(AutoConfigurable c, String key, String name) {
return new FormattedStringConfigurer(key, name, new String[]{PIECE_NAME, LABEL});
}
}
public static void drawLabel(Graphics g, String text, int x, int y, Font f, int hAlign, int vAlign, Color fgColor, Color bgColor, Color borderColor, boolean outline, Color outlineColor) {
g.setFont(f);
int buffer = g.getFontMetrics().getLeading();
int width = g.getFontMetrics().stringWidth(text)+2*buffer;
int height = g.getFontMetrics().getHeight();
int x0 = x;
int y0 = y;
switch (hAlign) {
case AL_CENTER:
x0 = x - width / 2;
break;
case AL_RIGHT:
x0 = x - width;
break;
}
switch (vAlign) {
case AL_CENTER:
y0 = y - height / 2;
break;
case AL_BOTTOM:
y0 = y - height;
break;
}
if (bgColor != null) {
g.setColor(bgColor);
g.fillRect(x0, y0, width, height);
}
if (borderColor != null) {
g.setColor(borderColor);
g.drawRect(x0, y0, width, height);
}
int y1 = y0 + g.getFontMetrics().getHeight() - g.getFontMetrics().getDescent();
int x1 = x0 + buffer;
if (outline && outlineColor != null) {
g.setColor(outlineColor);
g.drawString(text, x1-1, y1-1);
g.drawString(text, x1-1, y1+1);
g.drawString(text, x1+1, y1-1);
g.drawString(text, x1+1, y1+1);
}
g.setColor(fgColor);
g.drawString(text, x1, y1);
}
}