ZoomTool.java
/*
* Copyright (c) 2016 Vivid Solutions.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jtstest.testbuilder.ui.tools;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.Point2D;
import javax.swing.SwingUtilities;
import org.locationtech.jtstest.testbuilder.AppConstants;
import org.locationtech.jtstest.testbuilder.AppCursors;
/**
* @version 1.7
*/
public class ZoomTool extends BasicTool
{
private static ZoomTool singleton = null;
public static ZoomTool getInstance() {
if (singleton == null)
singleton = new ZoomTool(2, AppCursors.ZOOM);
return singleton;
}
private double zoomFactor = 2;
private Point mouseStart = null;
private Point mouseEnd = null;
private Point2D panStart;
public ZoomTool(double zoomFactor, Cursor cursor) {
super(cursor);
this.zoomFactor = zoomFactor;
}
public void mouseClicked(MouseEvent mouseEvent)
{
// determine if zoom in (left) or zoom out (right)
double realZoomFactor = SwingUtilities.isRightMouseButton(mouseEvent)
? (1d / zoomFactor) : zoomFactor;
panel().zoom(toModel(mouseEvent.getPoint()), realZoomFactor);
}
public void mousePressed(MouseEvent e)
{
mouseStart = e.getPoint();
mouseEnd = e.getPoint();
panStart = isPanGesture(e) ? toModel(mouseStart) : null;
}
public void mouseReleased(MouseEvent e) {
// don't process if mouse was dragged a very short distance
if (! isSignificantMouseMove(e.getPoint()))
return;
if (isPanGesture(e)) {
Point2D panEnd = toModel(e.getPoint());
PanTool.pan(panel(), panStart, panEnd);
return;
}
// no key -> do Zoom
panel().zoom(toModel(mouseStart), toModel(mouseEnd));
}
private static boolean isPanGesture(MouseEvent e) {
return e.isControlDown() || SwingUtilities.isRightMouseButton(e);
}
private boolean isPanning() {
return panStart != null;
}
public void mouseDragged(MouseEvent e)
{
Graphics g = getBandGraphics();
// erase old band
drawBand(g);
// draw new band
Point currPoint = e.getPoint();
mouseEnd = currPoint;
drawBand(g);
}
private Graphics getBandGraphics() {
Graphics g = panel().getGraphics();
g.setColor(AppConstants.BAND_CLR);
g.setXORMode(Color.white);
return g;
}
private void drawBand(Graphics g) {
if (isPanning()) {
drawLine(g, mouseStart, mouseEnd);
}
else {
drawRect(g, mouseStart, mouseEnd);
}
}
public void mouseWheelMoved(MouseWheelEvent e) {
/**
* Rolling wheel forward zooms in, backward zooms out
*/
double notches = e.getPreciseWheelRotation();
double zoomFactor = Math.abs(notches) * 4;
if (notches < 0 && zoomFactor > 0) zoomFactor = 1.0 / zoomFactor;
panel().zoom(toModel(e.getPoint()), zoomFactor);
}
private static final int MIN_MOVEMENT = 5;
private boolean isSignificantMouseMove(Point p)
{
int delta = Math.abs(mouseStart.x - p.x) + Math.abs(mouseStart.y - p.y);
if (delta < MIN_MOVEMENT)
return false;
return true;
}
public static void drawRect(Graphics g, Point p0, Point p1)
{
Point base = new Point(Math.min(p0.x, p1.x),
Math.min(p0.y, p1.y));
int width = Math.abs(p1.x - p0.x);
int height = Math.abs(p1.y - p0.y);
g.drawRect(base.x, base.y, width, height);
}
public static void drawLine(Graphics g, Point p0, Point p1)
{
g.drawLine(p0.x, p0.y, p1.x, p1.y);
}
}