Newer
Older
SimpleATN_M / src / main / java / jp / ac / kyutech / mns / ist / ZoomRegionHandler.java
@motoki miura motoki miura on 26 Apr 2022 5 KB first commit
package jp.ac.kyutech.mns.ist;


import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Stroke;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import jp.ac.kyutech.mns.ist.util.BUtil;
import edu.umd.cs.piccolo.PCamera;
import edu.umd.cs.piccolo.PCanvas;
import edu.umd.cs.piccolo.PNode;
import edu.umd.cs.piccolo.event.PDragSequenceEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolo.util.PAffineTransform;
import edu.umd.cs.piccolo.util.PBounds;

/**
 * ATNWindowで右ドラッグしながら青色のズーム範囲矩形を表示し,ズームする機能を実現するクラス
 * @author miuramo
 *
 */
public class ZoomRegionHandler extends PDragSequenceEventHandler {

	PPath selection;

	private Stroke[] strokes = null;

	private float strokeNum = 0;

	final static int NUM_STROKES = 10;

	final static int DASH_WIDTH = 15;

	Point2D cmp; // ドラッグ開始座標

	Point2D cp; //ドラッグ中の座標

	Point2D max_ext_cp; // 左上方向(通常とは逆方向)一番遠くにドラッグしたときの座標
	//	double dist_max_ext_cp; //そのときの距離
	PBounds initialBounds; //ドラッグ開始時の視野

	PNode pressN;
	PInputEvent pressEv = null;
	int dragCount = 0;
	PCanvas canvas;

	//	public boolean canceled_by_SimpleATN_EnterKey;

	public ZoomRegionHandler(PCanvas _canvas) {
		canvas = _canvas;

		float[] dash = { DASH_WIDTH, DASH_WIDTH };
		strokes = new Stroke[NUM_STROKES];
		for (int i = 0; i < NUM_STROKES; i++) {
			strokes[i] = new BasicStroke(2, BasicStroke.CAP_BUTT,
					BasicStroke.JOIN_MITER, 1, dash, i);
		}
	}

	public void startDrag(PInputEvent e) {
		super.startDrag(e);
		pressN = e.getPickedNode();
		pressEv = e;
		dragCount = 0;

		cmp = e.getPositionRelativeTo(canvas.getCamera());
		max_ext_cp = cmp; // 初期化
		selection = new PPath();
		selection.setPathToRectangle((float) cmp.getX(), (float) cmp.getY(), 0,
				0);
		selection.setStrokePaint(Color.blue);//青色
		selection.setPaint(null);
		selection.setStroke(strokes[0]);
		canvas.getCamera().addChild(selection);
		initialBounds = canvas.getCamera().getViewBounds();
	}

	public void drag(PInputEvent e) {
		super.drag(e);
		cp = e.getPositionRelativeTo(canvas.getCamera());
		dragCount++;
		float cp_cmp_x = (float)(cp.getX() - cmp.getX());
		float cp_cmp_y = (float)(cp.getY() - cmp.getY());

		if (selection != null){
			selection.setPathToRectangle((float) cmp.getX(), (float) cmp.getY(),
					cp_cmp_x, cp_cmp_y);

			// 右下にドラッグしているときの,青い点線矩形の点線パターンを変化させる
			float origStrokeNum = strokeNum;
			strokeNum = (strokeNum + 0.3f) % NUM_STROKES; 
			if ((int) strokeNum != (int) origStrokeNum) {
				selection.setStroke(strokes[(int) strokeNum]);
			}
			if (cp_cmp_x>10 && cp_cmp_y >10){
				selection.setStrokePaint(Color.blue);
			} else {
				selection.setStrokePaint(Color.magenta);
			}
		}

		//		 左上方向(通常とは逆方向)一番遠くにドラッグしたときの処理
		if (cp_cmp_x < 0 || cp_cmp_y < 0){			
			PCamera pc = canvas.getCamera();
			float f;
			if (cp_cmp_x < 0) f = Math.abs((float)(canvas.getWidth()/(canvas.getWidth() - cp.distance(cmp))));
			else f = Math.abs((float)((canvas.getWidth() - cp.distance(cmp))/canvas.getWidth()));
			PBounds pb = BUtil.zoomBounds(initialBounds, f);
			pc.animateViewToCenterBounds(pb, true, 0);
		}
	}

	public void endDrag(PInputEvent e) {
		super.endDrag(e);
		cp = e.getPositionRelativeTo(canvas.getCamera());
		if (dragCount < 3){
			//			if (pressN instanceof PText){
			//				//ポップアップメニュー
			//				new PopupMenu_forBase(pressEv, canvas, this);
			//			}
		}
		if (!PopupMenu_forZoomRegion.isopening /*&& !canceled_by_SimpleATN_EnterKey*/){
			if (selection != null) selection.removeFromParent();
			if (cmp.getX() < cp.getX() && cmp.getY() < cp.getY()) {
				if ((cp.getX()-cmp.getX())>10 && (cp.getY()-cmp.getY())>10){ //あまり小さければキャンセル


					// カメラ座標から,グローバル(パネル)座標への変換
					PAffineTransform at = canvas.getCamera().getViewTransform();
					if (selection != null){
						Rectangle2D globalb = selection.getGlobalBounds();
						Rectangle2D layerb = new Rectangle2D.Double();
						at.inverseTransform(globalb, layerb);
						canvas.getCamera().animateViewToCenterBounds(layerb, true, 1000);
					}
				}
			}
			selection = null;
			pressN = null;
		}
		//		canceled_by_SimpleATN_EnterKey = false;
	}

	public void dismissRegionLater(){
		if (selection != null){
			// カメラ座標から,グローバル(パネル)座標への変換
			//			PAffineTransform at = canvas.getCamera().getViewTransform();
			//			Rectangle2D globalb = selection.getGlobalBounds();
			//			Rectangle2D layerb = new Rectangle2D.Double();
			//			at.inverseTransform(globalb, layerb);
			//			PPath p = new PPath(layerb);
			//			p.setStroke(strokes[(int) strokeNum]);
			//			p.setStrokePaint(Color.orange);
			//			p.setPaint(null);
			//			canvas.getLayer().addChild(p);


			selection.removeFromParent();
			selection = null;
			pressN = null;
		}
	}
}