/* * Tiled Map Editor, (c) 2004-2006 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Adam Turk <aturk@biggeruniverse.com> * Bjorn Lindeijer <bjorn@lindeijer.nl> */ package tiled.core; import java.awt.Rectangle; import java.awt.geom.Area; import java.util.Properties; /** * A layer of a map. * * @see Map * @see MultilayerPlane */ public abstract class MapLayer implements Cloneable { /** MIRROR_HORIZONTAL */ public static final int MIRROR_HORIZONTAL = 1; /** MIRROR_VERTICAL */ public static final int MIRROR_VERTICAL = 2; /** ROTATE_90 */ public static final int ROTATE_90 = 90; /** ROTATE_180 */ public static final int ROTATE_180 = 180; /** ROTATE_270 */ public static final int ROTATE_270 = 270; protected String name; protected boolean isVisible = true; protected boolean bLocked = false; protected Map myMap; protected float opacity = 1.0f; protected Rectangle bounds; private Properties properties; public MapLayer() { bounds = new Rectangle(); setMap(null); properties = new Properties(); } /** * @param w width in tiles * @param h height in tiles */ public MapLayer(int w, int h) { this(new Rectangle(0, 0, w, h)); } public MapLayer(Rectangle r) { this(); setBounds(r); } /** * @param map the map this layer is part of */ MapLayer(Map map) { this(); setMap(map); } /** * @param map the map this layer is part of * @param w width in tiles * @param h height in tiles */ public MapLayer(Map map, int w, int h) { this(w, h); setMap(map); } /** * Performs a linear translation of this layer by (<i>dx, dy</i>). * * @param dx distance over x axis * @param dy distance over y axis */ public void translate(int dx, int dy) { bounds.x += dx; bounds.y += dy; } public abstract void rotate(int angle); public abstract void mirror(int dir); /** * Sets the bounds (in tiles) to the specified Rectangle. * * @param bounds */ protected void setBounds(Rectangle bounds) { this.bounds = new Rectangle(bounds); } /** * Sets the name of this layer. * * @param name the new name */ public void setName(String name) { this.name = name; } /** * Sets the map this layer is part of. * * @param map the Map object */ public void setMap(Map map) { myMap = map; } /** * Sets layer opacity. If it is different from the previous value and the * layer is visible, a MapChangedEvent is fired. * * @param opacity the new opacity for this layer */ public void setOpacity(float opacity) { if (this.opacity != opacity) { this.opacity = opacity; if (isVisible() && myMap != null) { myMap.fireMapChanged(); } } } /** * Sets the visibility of this map layer. If it changes from its current * value, a MapChangedEvent is fired. * * @param visible <code>true</code> to make the layer visible; * <code>false</code> to make it invisible */ public void setVisible(boolean visible) { if (isVisible != visible) { isVisible = visible; if (myMap != null) { myMap.fireMapChanged(); } } } /** * Sets the offset of this map layer. The offset is a distance by which to * shift this layer from the origin of the map. * * @param xOff x offset in tiles * @param yOff y offset in tiles */ public void setOffset(int xOff, int yOff) { bounds.x = xOff; bounds.y = yOff; } /** * Returns the name of this layer. * @return the name of the layer */ public String getName() { return name; } /** * Returns layer width in tiles. * @return layer width in tiles. */ public int getWidth() { return bounds.width; } /** * Returns layer height in tiles. * @return layer height in tiles. */ public int getHeight() { return bounds.height; } /** * Returns the layer bounds in tiles. * @return the layer bounds in tiles */ public Rectangle getBounds() { return new Rectangle(bounds); } /** * Assigns the layer bounds in tiles to the given rectangle. * @param rect the rectangle to which the layer bounds are assigned */ public void getBounds(Rectangle rect) { rect.setBounds(bounds); } /** * A convenience method to check if a point in tile-space is within * the layer boundaries. * * @param x the x-coordinate of the point * @param y the y-coordinate of the point * @return <code>true</code> if the point (x,y) is within the layer * boundaries, <code>false</code> otherwise. */ public boolean contains(int x, int y) { return bounds.contains(x, y); } /** * Returns layer opacity. * * @return layer opacity, ranging from 0.0 to 1.0 */ public float getOpacity() { return opacity; } /** * Returns whether this layer is visible. * * @return <code>true</code> if the layer is visible, <code>false</code> * otherwise. */ public boolean isVisible() { return isVisible; } /** * Merges the tile data of this layer with the specified layer. The calling * layer is considered the significant layer, and will overwrite the data * of the argument layer. At cells where the calling layer has no data, the * argument layer data is preserved. * * @param other the insignificant layer to merge with */ public abstract void mergeOnto(MapLayer other); public abstract void maskedMergeOnto(MapLayer other, Area mask); public abstract void copyFrom(MapLayer other); public abstract void maskedCopyFrom(MapLayer other, Area mask); public abstract MapLayer createDiff(MapLayer ml); /** * Unlike mergeOnto, copyTo includes the null tile when merging * * @see MapLayer#copyFrom * @see MapLayer#mergeOnto * @param other the layer to copy this layer to */ public abstract void copyTo(MapLayer other); public abstract boolean isEmpty(); /** * Creates a copy of this layer. * * @see Object#clone * @return a clone of this layer, as complete as possible * @exception CloneNotSupportedException */ @Override public Object clone() throws CloneNotSupportedException { MapLayer clone = (MapLayer) super.clone(); // Create a new bounds object clone.bounds = new Rectangle(bounds); clone.properties = (Properties) properties.clone(); return clone; } /** * @see MultilayerPlane#resize * * @param width the new width of the layer * @param height the new height of the layer * @param dx the shift in x direction * @param dy the shift in y direction */ public abstract void resize(int width, int height, int dx, int dy); /** * Get the locked status of the layer. * * @return whether the layer is locked * @see MapLayer#setLocked(boolean) */ public boolean getLocked() { return bLocked; } /** * Set the locked status of the layer. A locked layer can't be edited. * * @param lock <code>true</code> to lock the layer, <code>false</code> to * unlock the layer */ public void setLocked(boolean lock) { bLocked = lock; } public void setProperties(Properties p) { properties = p; } public Properties getProperties() { return properties; } public boolean canEdit() { return !getLocked() && isVisible(); } }