package jaist.css.covis.util;
import java.awt.AWTException;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import org.piccolo2d.PCamera;
import org.piccolo2d.PCanvas;
import org.piccolo2d.PInputManager;
import org.piccolo2d.event.PBasicInputEventHandler;
import org.piccolo2d.event.PInputEvent;
import org.piccolo2d.event.PInputEventFilter;
import org.piccolo2d.event.PPanEventHandler;
import org.piccolo2d.util.PBounds;
import org.piccolo2d.extras.event.PSelectionEventHandler;
import org.piccolo2d.extras.event.PZoomToEventHandler;
@SuppressWarnings("serial")
public class MyPCanvas extends PCanvas {
static PInputEventFilter b1mask = new PInputEventFilter(
InputEvent.BUTTON1_DOWN_MASK);
static PInputEventFilter b2mask = new PInputEventFilter(
InputEvent.BUTTON2_DOWN_MASK);
static PInputEventFilter b3mask = new PInputEventFilter(
InputEvent.BUTTON3_DOWN_MASK);
static PInputEventFilter disablemask = new PInputEventFilter(0);
PBasicInputEventHandler flowmenuEventHandler;
PSelectionEventHandler selectionEventHandler;
PPanEventHandler panEventHandler;
PZoomToEventHandler zoomeh;
Point2D cursorpoint;
public PCamera cam;
WheelZoomEventHandler wheelzoom;
public MouseWheelRotationListener wheelListener;
/**
* ホイール回転時のズーム方向.1または-1.デフォルトは1 = 手前(下)回転でズームイン
*/
// public int wheelrotationdirection = -1;
/**
* カーソルを中央にもってくるかどうか
*/
public boolean moveMouseCursorOnZoomIn = true;
Robot robot;
/**
* ズーム時の幅
*/
public float wheelZoomRatio = 1.0f;
public MyPCanvas() {
super();
initialize();
try {
robot = new Robot();
} catch (AWTException e) {
}
}
/**
* 擬似的なクリック
* @param x
* @param y
*/
public void pseudoClick(int x, int y){
getRoot().getDefaultInputManager().processEventFromCamera(new MouseEvent(this,0,0,MouseEvent.BUTTON1,x,y,1,true), MouseEvent.MOUSE_PRESSED, getCamera());
getRoot().getDefaultInputManager().processEventFromCamera(new MouseEvent(this,0,0,MouseEvent.BUTTON1,x,y,1,false), MouseEvent.MOUSE_RELEASED, getCamera());
}
public void setWheelRotationDirection(int d){
if (wheelzoom != null) wheelzoom.setDirection(d);
}
public void setMouseWheelRotationListener(MouseWheelRotationListener l){
wheelListener = l;
}
public void setWheelZoomRatio(float f){
wheelZoomRatio = f;
}
public PBasicInputEventHandler getWheelListener() {
return wheelzoom;
}
class WheelZoomEventHandler extends PBasicInputEventHandler {
public int direction = -1;
public void setDirection(int d){
direction = d;
}
public void mouseWheelRotated(PInputEvent e) {
if (!e.isControlDown() && !e.isShiftDown() && !e.isAltDown()) {
PCamera pc = getCamera();
// System.out.println("wheel rotation: " + pc.getAttribute("hoge"));
PBounds pb = pc.getViewBounds();
// System.out.println(pb.toString());
float f = 1.0f + (0.2f * direction * e.getWheelRotation());
if (e.getWheelRotation() //下に回すと正になるので
* direction < 0) {
pb = zoomBounds_focusbyCursor(pb, f);
} else {
pb = BUtil.zoomBounds(pb, f);
}
if (pb.x == 0 && pb.y == 0) {
System.out.println("ズームイン位置がまだ準備前");
return;
}
pc.animateViewToCenterBounds(pb, true, 0);
if (MyPCanvas.this.wheelListener != null) MyPCanvas.this.wheelListener.mouseWheelRotated(f);
}
}
}
public void initialize() {
cam = getCamera();
disablemask.rejectAllEventTypes();
wheelzoom = new WheelZoomEventHandler();
wheelzoom.setEventFilter(b2mask);
cam.addInputEventListener(wheelzoom);
// panEventHandler = new PPanEventHandler();
// getPanEventHandler().setEventFilter(disablemask);
// panEventHandler.setEventFilter(b2mask);
// addInputEventListener(panEventHandler);
getPanEventHandler().setEventFilter(b2mask);
// check current cursor position
addInputEventListener(new PInputManager() {
public void mouseMoved(PInputEvent e) {
cursorpoint = e.getCanvasPosition();
try {
e.getPath().getPathTransformTo(getLayer()).inverseTransform(cursorpoint, cursorpoint);
} catch (RuntimeException ex) {
cursorpoint = e.getPosition(); // Camera付きのメニューボタンや,背景部分(PCamera)のとき
}
// TODO: 本来であればRuntimeExceptionを出さずに処理したいのだが..
// e.getPickedNode().localToParent(cursorpoint);
// System.out.println(e.getPickedNode().getRoot().getClass().getName());
// if (e.getPickedNode() instanceof PCamera)
// else cursorpoint = e.getPositionRelativeTo(getLayer());
catch (NoninvertibleTransformException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
}
public PBounds zoomBounds_focusbyCursor(PBounds pb, double rate) {
double x = pb.getX();
double y = pb.getY();
double w = pb.getWidth();
double h = pb.getHeight();
double nw = w * rate;
double nh = h * rate;
Point2D camcp = cam.getViewBounds().getCenter2D();
double camcx = camcp.getX();
double camcy = camcp.getY();
// System.out.println("camcp "+camcx+" "+camcy);
double curx = cursorpoint.getX();
double cury = cursorpoint.getY();
// System.out.println("cursor "+curx+" "+cury);
double nx = x - (nw - w) / 2 + curx - camcx;
double ny = y - (nh - h) / 2 + cury - camcy;
PBounds ret = new PBounds(nx, ny, nw, nh);
cursorpoint = ret.getCenter2D();
if (moveMouseCursorOnZoomIn) {
moveCursorPointCenter();
} else {
}
return ret;
}
public void moveCursorPointCenter() {
Point canvasglobalp = getLocationOnScreen();
int canvasw = getWidth();
int canvash = getHeight();
if (robot != null)
robot.mouseMove((int) (canvasglobalp.getX() + canvasw / 2),
(int) (canvasglobalp.getY() + canvash / 2));
}
}
//@SuppressWarnings("serial")
//class MyPCanvas_noPointerZoom extends MyPCanvas {
//public PBounds zoomBounds_focusbyCursor(PBounds pb, double rate) {
//return BUtil.zoomBounds(pb, rate);
//}
//}