/*
* Copyright 2003-2010 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package tufts.vue;
import tufts.Util;
import java.awt.Rectangle;
import java.awt.event.InputEvent;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Point2D;
import java.awt.event.*;
import javax.swing.JViewport;
import javax.swing.JScrollPane;
/**
* Extension of MouseEvent for events that happen on an instance of LWMap
* in a MapViewer.
*
* @version $Revision: 1.25 $ / $Date: 2010-02-03 19:17:40 $ / $Author: mike $
* @author Scott Fraize
*/
/*
* Todo arch: rename LWMouseEvent and package with all the LW model classes as
* the primary gui interaction channel between the model and a gui panel displaying a map.
* Will need to create a viewer interface to generically handle conversions between
* viewer coordinates and LWMap coordinates.
*/
public class MapMouseEvent extends MouseEvent
{
private static final int COMMAND_MASK = VueUtil.isMacPlatform() ? InputEvent.META_MASK : InputEvent.ALT_MASK;
private static final LWComponent UNSET = new LWComponent();
float mapX;
float mapY;
LWComponent picked = UNSET;
LWComponent dragRequest;
Rectangle selectorBox;
int pressX;
int pressY;
/** did this mouse result in VUE / MapViewer getting new focus? */
public final boolean onFocus;
//private Point2D.Float nodePoint;
public MapMouseEvent(MouseEvent e, float mapX, float mapY, Rectangle selectorBox, boolean onFocus)
{
super(e.getComponent(),
e.getID(),
e.getWhen(),
e.getModifiers() | e.getModifiersEx(),
e.getX(),
e.getY(),
e.getClickCount(),
e.isPopupTrigger(),
e.getButton());
this.mapX = mapX;
this.mapY = mapY;
this.selectorBox = selectorBox;
this.onFocus = onFocus;
}
public MapMouseEvent(MouseEvent e)
{
this(e, 0f, 0f, null, false);
this.mapX = getViewer().screenToMapX(e.getX());
this.mapY = getViewer().screenToMapY(e.getY());
}
public MapMouseEvent(MouseEvent e, LWComponent c)
{
this(e);
setPicked(c);
}
public MapMouseEvent(MouseEvent e, Rectangle selectorBox)
{
this(e);
setSelectorBox(selectorBox);
}
public boolean isCommandDown() {
return (getModifiers() & COMMAND_MASK) != 0;
}
public void setMousePress(int pressX, int pressY)
{
this.pressX = pressX;
this.pressY = pressY;
}
public int getDeltaPressX() { return getX() - pressX; }
public int getDeltaPressY() { return getY() - pressY; }
public void setDragRequest(LWComponent c) { this.dragRequest = c; }
public LWComponent getDragRequest() { return this.dragRequest; }
public Rectangle getSelectorBox() {
return this.selectorBox;
}
void setSelectorBox(Rectangle r) {
this.selectorBox = r;
}
public Rectangle2D getMapSelectorBox()
{
return getViewer().screenToMapRect(this.selectorBox);
}
public MapViewer getViewer() {
// todo perf: cache viewer
Object src = super.getSource();
if (src instanceof JViewport)
return (MapViewer) ((JViewport)src).getView();
else if (src instanceof JScrollPane)
return (MapViewer) ((JScrollPane)src).getViewport().getView();
else
return (MapViewer) src;
}
public LWMap getMap() {
return getViewer().getMap();
}
public LWComponent getFocal() {
return getViewer().getFocal();
}
public float getMapX() {
return mapX;
}
public float getMapY() {
return mapY;
}
public Point2D.Float getMapPoint() {
return new Point2D.Float(mapX, mapY);
}
// // TODO: these handling new coord system??
// public float getComponentX() {
// getPicked();
// return picked == null ? Float.NaN : (mapX - picked.getX()) / picked.getScaleF();
// }
// public float getComponentY() {
// getPicked();
// return picked == null ? Float.NaN : (mapY - picked.getY()) / picked.getScaleF();
// }
// public Point2D.Float getComponentPoint() {
// return new Point2D.Float(getComponentX(), getComponentY());
// }
public Point2D.Float getLocalPoint(LWComponent local) {
if (local != picked && picked != null && picked != UNSET) {
if (DEBUG.Enabled)
Util.printStackTrace("warning: local != picked"
+ "\n\tpicked: " + picked
+ "\n\t local: " + local);
}
return local.transformMapToZeroPoint(new Point2D.Float(mapX, mapY));
// if (nodePoint == null) {
// nodePoint = new Point2D.Float(mapX, mapY);
// local.transformMapToZeroPoint(nodePoint, nodePoint);
// }
// return nodePoint;
}
public Point2D.Float getFocalPoint() {
if (getFocal() == getMap())
return getMapPoint();
else
return getFocal().transformMapToZeroPoint(new Point2D.Float(mapX, mapY));
}
public LWComponent getPicked() {
if (picked == UNSET) {
if (DEBUG.PICK) out("computing picked...");
setPicked(getViewer().pickNode(mapX, mapY));
} else
if (DEBUG.PICK) out("picked is already: " + picked);
return picked;
}
void setPicked(LWComponent c) {
if (DEBUG.PICK) out("setting picked to " + c);
this.picked = c;
}
private void out(String s) {
System.out.println("MapMouseEvent@"
+ Integer.toHexString(hashCode())
+ "[" +
getViewer()
+ "]: " + s
);
}
public String paramString() {
return super.paramString()
// + ",cx=" + getComponentX()
// + ",cy=" + getComponentY()
+ ",hit=" + (picked == UNSET ? "<unset>" : picked);
}
}