/* * $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.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.util.Collections; import java.util.List; import VASSAL.build.AutoConfigurable; import VASSAL.configure.StringEnum; import VASSAL.configure.VisibilityCondition; import VASSAL.tools.ArrayUtils; import VASSAL.tools.SequenceEncoder; import VASSAL.tools.image.ImageUtils; import VASSAL.tools.imageop.AbstractTileOpImpl; import VASSAL.tools.imageop.ImageOp; import VASSAL.tools.imageop.Op; public class ImageItem extends Item { public static final String TYPE = "Image"; //$NON-NLS-1$ public static final String SRC_VARIABLE = "Specified in individual images"; public static final String SRC_FIXED = "Fixed for this layout"; protected static final String IMAGE = "image"; //$NON-NLS-1$ public static final String SOURCE = "source"; //$NON-NLS-1$ protected String imageSource = SRC_FIXED; protected String imageName = ""; //$NON-NLS-1$ @Deprecated protected Image image = null; protected ImageOp srcOp; protected Rectangle imageBounds = new Rectangle(); public ImageItem() { super(); } public ImageItem(GamePieceLayout l) { super(l); } public ImageItem(GamePieceLayout l, String n) { this(l); setConfigureName(n); } public String[] getAttributeDescriptions() { return ArrayUtils.insert( super.getAttributeDescriptions(), 2, "Image: ", "Image is: " ); } public Class<?>[] getAttributeTypes() { return ArrayUtils.insert( super.getAttributeTypes(), 2, new Class<?>[]{ Image.class, TextSource.class } ); } public String[] getAttributeNames() { return ArrayUtils.insert( super.getAttributeNames(), 2, IMAGE, SOURCE ); } public void setAttribute(String key, Object o) { if (IMAGE.equals(key)) { if (o instanceof String) { imageName = (String) o; } else { if (o == null) { imageName = null; } else { imageName = ((File) o).getName(); } } } else if (SOURCE.equals(key)) { imageSource = (String) o; } else { super.setAttribute(key, o); } if (layout != null) { layout.refresh(); } } public String getAttributeValueString(String key) { if (IMAGE.equals(key)) { return imageName; } else if (SOURCE.equals(key)) { return imageSource; } else { return super.getAttributeValueString(key); } } public VisibilityCondition getAttributeVisibility(String name) { if (ROTATION.equals(name)) { return falseCond; } else if (IMAGE.equals(name)) { return fixedCond; } else { return super.getAttributeVisibility(name); } } private VisibilityCondition falseCond = new VisibilityCondition() { public boolean shouldBeVisible() { return false; } }; private VisibilityCondition fixedCond = new VisibilityCondition() { public boolean shouldBeVisible() { return imageSource.equals(SRC_FIXED); } }; public static class TextSource extends StringEnum { public String[] getValidValues(AutoConfigurable target) { return new String[] { SRC_VARIABLE, SRC_FIXED }; } } public void draw(Graphics g, GamePieceImage defn) { loadImage(defn); Point origin = layout.getPosition(this); if (isAntialias()) { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } else { ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); } if (srcOp != null) { final BufferedImage img = srcOp.getImage(); if (img != null) { g.drawImage(img, origin.x, origin.y, null); } } } public String getType() { return TYPE; } public Dimension getSize() { return imageBounds.getSize(); } public boolean isFixed() { return imageSource.equals(SRC_FIXED); } protected void loadImage(GamePieceImage defn) { ImageItemInstance Ii = null; if (defn != null) { Ii = defn.getImageInstance(getConfigureName()); } if (Ii == null) { Ii = new ImageItemInstance(); } String iName; if (imageSource.equals(SRC_FIXED)) { iName = imageName; } else { iName = Ii.getImageName(); } // image = null; if (iName != null) { if (iName.trim().length() == 0) { srcOp = BaseOp.op; } else { /* try { image = GameModule.getGameModule().getDataArchive().getCachedImage(iName); // imageBounds = DataArchive.getImageBounds(image); imageBounds = ImageUtils.getBounds((BufferedImage) image); } catch (IOException e) { } */ srcOp = Op.load(iName); } imageBounds = ImageUtils.getBounds(srcOp.getSize()); } else { imageBounds = new Rectangle(); } } protected static final class BaseOp extends AbstractTileOpImpl { private BaseOp() { } private static final BaseOp op = new BaseOp(); public BufferedImage eval() throws Exception { final BufferedImage img = ImageUtils.createCompatibleTranslucentImage(10, 10); final Graphics2D bg = img.createGraphics(); bg.setColor(Color.black); bg.drawRect(0, 0, 9, 9); bg.drawLine(0, 0, 9, 9); bg.drawLine(0, 9, 9, 0); bg.dispose(); return img; } protected void fixSize() { } @Override public Dimension getSize() { return new Dimension(10,10); } @Override public int getWidth() { return 10; } @Override public int getHeight() { return 10; } public List<VASSAL.tools.opcache.Op<?>> getSources() { return Collections.emptyList(); } // NB: This ImageOp doesn't need custom equals() or hashCode() // because it's a singleton. } public static Item decode(GamePieceLayout l, String s) { final SequenceEncoder.Decoder sd = new SequenceEncoder.Decoder(s, ';'); final ImageItem item = new ImageItem(l); sd.nextToken(); item.imageName = sd.nextToken(""); //$NON-NLS-1$ item.imageSource = sd.nextToken(SRC_FIXED); return item; } public String encode() { final SequenceEncoder se1 = new SequenceEncoder(TYPE, ';'); se1.append(imageName) .append(imageSource); final SequenceEncoder se2 = new SequenceEncoder(se1.getValue(), '|'); se2.append(super.encode()); return se2.getValue(); } }