/*
* 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.client.tool;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import com.t3.client.ScreenPoint;
import com.t3.client.ui.zone.ZoneOverlay;
import com.t3.client.ui.zone.ZoneRenderer;
import com.t3.client.walker.ZoneWalker;
import com.t3.image.ImageUtil;
import com.t3.model.CellPoint;
import com.t3.model.Path;
import com.t3.model.ZonePoint;
import com.t3.swing.SwingUtil;
import com.t3.util.GraphicsUtil;
/**
*/
public class MeasureTool extends DefaultTool implements ZoneOverlay {
private ZoneWalker walker;
private Path<ZonePoint> gridlessPath;
public MeasureTool() {
try {
setIcon(new ImageIcon(ImageUtil.getImage("com/t3/client/image/tool/ruler-blue.png")));
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
@Override
public String getTooltip() {
return "tool.measure.tooltip";
}
@Override
public String getInstructions() {
return "tool.measure.instructions";
}
@Override
public void paintOverlay(ZoneRenderer renderer, Graphics2D g) {
if (walker == null && gridlessPath == null) {
return;
}
if (walker != null) {
renderer.renderPath(g, walker.getPath(), renderer.getZone().getGrid().getDefaultFootprint());
ScreenPoint sp = walker.getLastPoint().convertToScreen(renderer);
int y = (int) sp.y - 10;
int x = (int) sp.x + (int) (renderer.getScaledGridSize() / 2);
GraphicsUtil.drawBoxedString(g, Integer.toString(walker.getDistance()), x, y);
} else {
Object oldAA = SwingUtil.useAntiAliasing(g);
g.setColor(Color.black);
ScreenPoint lastPoint = null;
for (ZonePoint zp : gridlessPath.getCellPath()) {
if (lastPoint == null) {
lastPoint = ScreenPoint.fromZonePoint(renderer, zp);
continue;
}
ScreenPoint nextPoint = ScreenPoint.fromZonePoint(renderer, zp.x, zp.y);
g.drawLine((int) lastPoint.x, (int) lastPoint.y, (int) nextPoint.x, (int) nextPoint.y);
lastPoint = nextPoint;
}
// distance
double c = 0;
ZonePoint lastZP = null;
for (ZonePoint zp : gridlessPath.getCellPath()) {
if (lastZP == null) {
lastZP = zp;
continue;
}
int a = lastZP.x - zp.x;
int b = lastZP.y - zp.y;
c += Math.sqrt(a * a + b * b);
lastZP = zp;
}
// int a = lastPoint.x - (set.offsetX + token.getX());
// int b = lastPoint.y - (set.offsetY + token.getY());
//
// c += Math.sqrt(a*a + b*b)/zone.getUnitsPerCell();
c /= renderer.getZone().getGrid().getSize();
c *= renderer.getZone().getUnitsPerCell();
String distance = String.format("%.1f", c);
ScreenPoint sp = ScreenPoint.fromZonePoint(renderer, lastZP.x, lastZP.y);
GraphicsUtil.drawBoxedString(g, distance, (int) sp.x, (int) sp.y - 20);
SwingUtil.restoreAntiAliasing(g, oldAA);
}
}
@Override
protected void installKeystrokes(Map<KeyStroke, Action> actionMap) {
super.installKeystrokes(actionMap);
actionMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
if (walker == null && gridlessPath == null) {
return;
}
// Waypoint
if (walker != null) {
CellPoint cp = renderer.getZone().getGrid().convert(new ScreenPoint(mouseX, mouseY).convertToZone(renderer));
walker.toggleWaypoint(cp);
} else {
gridlessPath.addWayPoint(new ScreenPoint(mouseX, mouseY).convertToZone(renderer));
gridlessPath.addPathCell(new ScreenPoint(mouseX, mouseY).convertToZone(renderer));
}
}
});
}
////
// MOUSE LISTENER
@Override
public void mousePressed(java.awt.event.MouseEvent e) {
ZoneRenderer renderer = (ZoneRenderer) e.getSource();
if (SwingUtilities.isLeftMouseButton(e)) {
if (renderer.getZone().getGrid().getCapabilities().isPathingSupported()) {
CellPoint cellPoint = renderer.getCellAt(new ScreenPoint(e.getX(), e.getY()));
walker = renderer.getZone().getGrid().createZoneWalker();
walker.addWaypoints(cellPoint, cellPoint);
} else {
gridlessPath = new Path<ZonePoint>();
gridlessPath.addPathCell(new ScreenPoint(e.getX(), e.getY()).convertToZone(renderer));
// Add a second one that will be replaced as the mouse moves around the screen
gridlessPath.addPathCell(new ScreenPoint(e.getX(), e.getY()).convertToZone(renderer));
}
renderer.repaint();
return;
}
super.mousePressed(e);
}
@Override
public void mouseReleased(MouseEvent e) {
ZoneRenderer renderer = (ZoneRenderer) e.getSource();
if (SwingUtilities.isLeftMouseButton(e)) {
walker = null;
gridlessPath = null;
renderer.repaint();
return;
}
super.mouseReleased(e);
}
////
// MOUSE MOTION LISTENER
@Override
public void mouseDragged(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
super.mouseDragged(e);
return;
}
ZoneRenderer renderer = (ZoneRenderer) e.getSource();
if (walker != null && renderer.getZone().getGrid().getCapabilities().isPathingSupported()) {
CellPoint cellPoint = renderer.getCellAt(new ScreenPoint(e.getX(), e.getY()));
walker.replaceLastWaypoint(cellPoint);
} else if (gridlessPath != null) {
gridlessPath.replaceLastPoint(new ScreenPoint(e.getX(), e.getY()).convertToZone(renderer));
}
renderer.repaint();
}
}