package com.opendoorlogistics.studio.components.map.plugins;
import java.awt.Cursor;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import com.opendoorlogistics.api.standardcomponents.map.MapApi;
import com.opendoorlogistics.api.standardcomponents.map.MapApiListeners;
import com.opendoorlogistics.api.standardcomponents.map.MapMode;
import com.opendoorlogistics.api.standardcomponents.map.MapPlugin;
import com.opendoorlogistics.api.standardcomponents.map.MapPopupMenu;
import com.opendoorlogistics.api.standardcomponents.map.MapToolbar;
import com.opendoorlogistics.api.standardcomponents.map.StandardMapMenuOrdering;
import com.opendoorlogistics.studio.components.map.AbstractMapMode;
import com.opendoorlogistics.studio.components.map.plugins.utils.PluginUtils;
import com.opendoorlogistics.utils.ui.Icons;
import com.opendoorlogistics.utils.ui.SimpleAction;
public class PanMapPlugin implements MapPlugin{
@Override
public void initMap(MapApi api) {
PanMapState ret = new PanMapState(api);
api.registerOnBuildToolbarListener(ret, StandardMapMenuOrdering.NAVIGATE);
api.registerOnBuildContextMenuListener(ret, 0);
api.registerKeyListener(ret, 0);
api.setMapMode(ret);
api.setDefaultMapMode(ret);
}
@Override
public String getId(){
return "com.opendoorlogistics.studio.components.map.plugins.PanMapPlugin";
}
private static class PanMapState extends AbstractMapMode implements MapApiListeners.OnBuildToolbarListener,MapApiListeners.OnBuildContextMenu, MapMode{
private final MapApi api;
private final double pan = 0.25;
private final Cursor cursor;
public PanMapState(MapApi api) {
this.api = api;
cursor = PluginUtils.createCursor("arrow-out-32x32.png", 17, 15);
}
@Override
public void onBuildToolbar(final MapApi api, MapToolbar toolBar) {
for(Action action : createActions()){
toolBar.add(action, "navigate");
}
}
@Override
public Cursor getCursor() {
return cursor;
}
private class PanAction extends SimpleAction {
double x;
double y;
int key;
PanAction(String name, String tooltip, String smallIconPng, double x, double y, int keyEvent) {
super(name, tooltip, smallIconPng);
this.x = x;
this.y = y;
this.key = keyEvent;
// register myself in action map
// registerActionKeyEvent(this, keyEvent);
}
@Override
public void actionPerformed(ActionEvent e) {
Rectangle bounds = api.getWorldBitmapViewport();
double dx = x * bounds.width;
double dy = y * bounds.height;
Point2D centre = api.getWorldBitmapMapCentre();
centre = new Point2D.Double(centre.getX() + dx, centre.getY() + dy);
api.setView(api.getZoom(), centre);
}
}
public ArrayList<Action> createActions() {
ArrayList<Action> ret = new ArrayList<Action>();
ret.add(new SimpleAction("Zoom to all", "Zoom to all", "small_zoom_best_fit.png") {
@Override
public void actionPerformed(ActionEvent e) {
api.setViewToBestFit(api.getMapDataApi().getFilteredAllLayersTable(true));
}
});
Action zoomIn = new SimpleAction("Zoom in", "Zoom in", "zoom-in-3.png") {
@Override
public void actionPerformed(ActionEvent e) {
api.setZoom(api.getZoom() - 1);
}
};
// registerActionKeyEvent(zoomIn, KeyEvent.VK_PLUS);
ret.add(zoomIn);
Action zoomOut = new SimpleAction("Zoom out", "Zoom out", "zoom-out-3.png") {
@Override
public void actionPerformed(ActionEvent e) {
api.setZoom(api.getZoom() + 1);
}
};
ret.add(zoomOut);
// create pan buttons
ret.add(leftAction());
ret.add(rightAction());
ret.add(upAction());
ret.add(downAction());
// create move mode
ImageIcon icon = Icons.loadFromStandardPath("arrow-out-16x16.png");
AbstractAction action = new AbstractAction("Move mode",icon) {
@Override
public void actionPerformed(ActionEvent e) {
api.setMapMode(PanMapState.this);
}
};
PluginUtils.initAction("Move mode", "Drag the map to look around.", "arrow-out-16x16.png", action);
ret.add(action);
return ret;
}
private PanAction downAction() {
return new PanAction("Pan right", "Pan right", "arrow-right-3-16x16.png", pan, 0, KeyEvent.VK_RIGHT);
}
private PanAction upAction() {
return new PanAction("Pan down", "Pan down", "arrow-down-3-16x16.png", 0, pan, KeyEvent.VK_DOWN);
}
private PanAction rightAction() {
return new PanAction("Pan up", "Pan up", "arrow-up-3-16x16.png", 0, -pan, KeyEvent.VK_UP);
}
private PanAction leftAction() {
return new PanAction("Pan left", "Pan left", "arrow-left-3-16x16.png", -pan, 0, KeyEvent.VK_LEFT);
}
@Override
public void mouseDragged(MouseEvent evt) {
super.mouseDragged(evt);
if(isDragging()){
// do the move to account for the last drag
Point2D centre = api.getWorldBitmapMapCentre();
api.setView(api.getZoom(), new Point2D.Double(centre.getX() - getDragEndPoint().getX() + getDragStartPoint().getX(),
centre.getY()- getDragEndPoint().getY() + getDragStartPoint().getY()));
// and update the drag start point as it is now effectively the current point
setDragStartPoint(getDragEndPoint());
}
}
@Override
public void keyPressed(KeyEvent e) {
for(PanAction panAction : new PanAction[]{leftAction(),rightAction(),upAction(),downAction()}){
if(e.getKeyCode() == panAction.key){
panAction.actionPerformed(null);
}
}
}
@Override
public void onBuildContextMenu(MapApi api, MapPopupMenu menu) {
for(Action action : createActions()){
menu.add(action, "navigate");
}
}
}
}