/**
*
*/
package org.openjump.core.ui.plugin.view;
import java.awt.event.KeyEvent;
import java.awt.geom.NoninvertibleTransformException;
import javax.swing.JInternalFrame;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
import com.vividsolutions.jump.workbench.plugin.PlugInContext;
import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
import com.vividsolutions.jump.workbench.ui.TaskFrame;
import com.vividsolutions.jump.workbench.ui.Viewport;
/**
* Plug in for navigation with keyboards keys. <br/>
* Navigation is as follows:<br/>
* Arrows keys move the viewport.<br/>
* Page down and up are zoom in and zoom out, respectively<br/>
* Home key zooms in or out to full extent<br/>
* Pan and zoom percentage is, by default, 20%
*
* @author Ugo Taddei <taddei@lat-lon.de>
*
*/
public class InstallKeyPanPlugIn extends AbstractPlugIn {
private static final int NORTH = 0;
private static final int EAST = 1;
private static final int SOUTH = 2;
private static final int WEST = 3;
private static final int ZOOM_IN = 4;
private static final int ZOOM_OUT = 5;
/* matrix defining directions */
private static final int[][] DIRECTIONS =
{ {0, -1, 0, -1}, //NORTH
{-1, 0, -1, 0}, //EAST
{0, 1, 0, 1},
{1, 0, 1, 0},
{1, 1, -1, -1}, //ZOOM_IN
{-1, -1, 1, 1}};//ZOOM_OUT
private static double panPercentage;
/**
* Default constructor
*/
public InstallKeyPanPlugIn() {
this( 0.2 );
}
/**
*
* Creates a new plug-in with pan_percentage as pan percentage value
*
* pan_percentage The value in percent of screen size to pan/zoom. Accepted
* values are in the range 0 < percentage <= 1
*/
public InstallKeyPanPlugIn( double panPercentag ) {
super();
setPanPercentage( panPercentag );
}
public boolean execute(PlugInContext context) throws Exception {
context.getLayerViewPanel().getViewport().zoomToFullExtent();
return true;
}
private static Envelope createEnvelopeFromDirection( Envelope oldEnvelope, int direction) {
double oldWidth = panPercentage*oldEnvelope.getWidth();
double oldHeight = panPercentage*oldEnvelope.getHeight();
double dxPlus = DIRECTIONS[ direction ][0]*oldWidth;
double dyPlus = DIRECTIONS[ direction ][1]*oldHeight;
double dxMinus = DIRECTIONS[ direction ][2]*oldWidth;
double dyMinus = DIRECTIONS[ direction ][3]*oldHeight;
return new Envelope(
oldEnvelope.getMinX() - dxMinus,
oldEnvelope.getMaxX() - dxPlus,
oldEnvelope.getMinY() - dyMinus,
oldEnvelope.getMaxY() - dyPlus);
}
public boolean pan( JInternalFrame jif, int direction ) {
if (jif instanceof TaskFrame) {
TaskFrame taskFrame = (TaskFrame) jif;
LayerViewPanel lvp = taskFrame.getLayerViewPanel();
Viewport vp = lvp.getViewport();
Envelope oldEnvelope = vp.getEnvelopeInModelCoordinates();
try {
vp.zoom(
createEnvelopeFromDirection( oldEnvelope, direction) );
} catch (NoninvertibleTransformException e1) {
e1.printStackTrace();
return false;
}
}
return true;
}
public void initialize(PlugInContext context) throws Exception {
super.initialize(context);
AbstractPlugIn[] plugIns =
{ this, new PanHelper( NORTH ), new PanHelper( EAST ),
new PanHelper( SOUTH), new PanHelper( WEST ),
new PanHelper( ZOOM_IN ), new PanHelper( ZOOM_OUT ) };
int[] keys = { KeyEvent.VK_HOME, KeyEvent.VK_UP, KeyEvent.VK_RIGHT,
KeyEvent.VK_DOWN, KeyEvent.VK_LEFT, KeyEvent.VK_PAGE_DOWN,
KeyEvent.VK_PAGE_UP };
for (int i = 0; i < keys.length; i++) {
context.getWorkbenchContext().getWorkbench().getFrame()
.addKeyboardShortcut( keys[i], 0, plugIns[i], null);
}
}
public String getName() { return ""; }
/**
* Get the pan/zoom percentage, a value between 0 and 1. Deafult is 0.25 (=25%)
*/
public static double getPanPercentage() {
return 2*panPercentage;
}
/**
* Set the pan percentage. Legal values are between greater than 0 and less than
* or equal to 1.0
* @param panPercent The value in percent of screen size to pan/zoom. Accepted
* values are in the range 0 < percentage <= 1
*/
public static void setPanPercentage(double panPercent ) {
if ( panPercent <= 0 || panPercent > 1d ) {
throw new IllegalArgumentException( "Accepted values are in the "
+" range 0 < percentage <= 1" );
}
//have percentage, otherwise it's percentage value in each direction
//making it twice as much!
panPercentage = panPercent/2d;
}
/**
* Helper class to pan in the direction given in constructor
*/
private class PanHelper extends AbstractPlugIn {
private final int direction;
public PanHelper( int direction ) {
this.direction = direction;
}
public boolean execute(PlugInContext context) throws Exception {
return pan( context.getWorkbenchFrame().getActiveInternalFrame(), direction );
}
}
}