/*
* Copyright (c) 2014 tabletoptool.com team.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/gpl.html
*
* Contributors:
* rptools.com team - initial implementation
* tabletoptool.com team - further development
*/
package com.t3.model.drawing;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import com.t3.model.ZonePoint;
import com.t3.xstreamversioned.version.SerializationVersion;
/**
* The blast template draws a square for D&D 4e
*
* @author jgorrell
* @version $Revision: $ $Date: $ $Author: $
*/
@SerializationVersion(0)
public class BlastTemplate extends ConeTemplate {
/*---------------------------------------------------------------------------------------------
* Instance Variables
*-------------------------------------------------------------------------------------------*/
/**
* Renderer for the blast. The {@link Shape} is just a rectangle.
*/
private ShapeDrawable renderer = new ShapeDrawable(new Rectangle());
private int offsetX;
private int offsetY;
/*---------------------------------------------------------------------------------------------
* Instance Methods
*-------------------------------------------------------------------------------------------*/
/**
* This methods adjusts the rectangle in the renderer to match the new radius, vertex, or location.
*/
private void adjustRectangle() {
if (getZoneReference() == null) return;
int gridSize = getZoneReference().value().getGrid().getSize();
int size = getRadius() * gridSize;
Rectangle r = (Rectangle)renderer.getShape();
r.setBounds(getVertex().x, getVertex().y, size, size);
r.x += offsetX * gridSize;
r.y += offsetY * gridSize;
}
/*---------------------------------------------------------------------------------------------
* Overridden *Template Methods
*-------------------------------------------------------------------------------------------*/
@Override
public Rectangle getBounds() {
Rectangle r = new Rectangle(renderer.getShape().getBounds());
// We don't know pen width, so add some padding to account for it
r.x -= 5;
r.y -= 5;
r.width += 10;
r.height += 10;
return r;
}
/**
* Defines the blast based on the specified square
*
* @param relX The X coordinate of the control square relative to the origin square
* @param relY The Y coordinate of the control square relative to the origin square
*/
public void setControlCellRelative(int relX, int relY) {
relX = Math.max(Math.min(relX, MAX_RADIUS), -MAX_RADIUS);
relY = Math.max(Math.min(relY, MAX_RADIUS), -MAX_RADIUS);
int radius = Math.max(Math.abs(relX), Math.abs(relY));
// Number of cells along axis of smaller offset we need to shift the square in order to "center" the blast
int centerOffset = -(radius / 2);
// Smallest delta we can apply to centerOffset and still have valid placement
int lowerBound = -((radius + 1) / 2);
// Largest delta we can apply to centerOffset and still have valid placement
int upperBound = (radius / 2) + 1;
setRadius(radius);
// The larger magnitude offset determines size and gross positioning, the smaller determines fine positioning
if (Math.abs(relX) > Math.abs(relY)) {
if (relX > 0) {
offsetX = 1;
} else {
offsetX = -radius;
}
offsetY = centerOffset + Math.min(Math.max(lowerBound, relY), upperBound);
} else {
if (relY > 0) {
offsetY = 1;
} else {
offsetY = -radius;
}
offsetX = centerOffset + Math.min(Math.max(lowerBound, relX), upperBound);
}
adjustRectangle();
}
/**
* @see com.t3.model.drawing.AbstractTemplate#setVertex(com.t3.model.ZonePoint)
*/
@Override
public void setVertex(ZonePoint vertex) {
super.setVertex(vertex);
adjustRectangle();
}
/**
* @see com.t3.model.drawing.AbstractTemplate#getDistance(int, int)
*/
@Override
public int getDistance(int x, int y) {
return Math.max(x, y);
}
/*---------------------------------------------------------------------------------------------
* Overridden AbstractDrawing Methods
*-------------------------------------------------------------------------------------------*/
/**
* @see com.t3.model.drawing.AbstractDrawing#draw(java.awt.Graphics2D)
*/
@Override
protected void draw(Graphics2D g) {
renderer.draw(g);
}
/**
* @see com.t3.model.drawing.AbstractDrawing#drawBackground(java.awt.Graphics2D)
*/
@Override
protected void drawBackground(Graphics2D g) {
Composite old = g.getComposite();
if (old != AlphaComposite.Clear)
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, DEFAULT_BG_ALPHA));
renderer.drawBackground(g);
g.setComposite(old);
}
}