/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt.client.controller; import org.geomajas.geometry.Coordinate; import org.geomajas.gwt.client.map.MapView.ZoomOption; import org.geomajas.gwt.client.map.RenderSpace; import org.geomajas.gwt.client.spatial.Bbox; import org.geomajas.gwt.client.widget.MapWidget; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.HumanInputEvent; import com.google.gwt.event.dom.client.MouseOutEvent; import com.smartgwt.client.types.Cursor; /** * Handle panning by dragging the map. Also allows zoom to rectangle when using shift or ctrl when you start to drag. * Double clicking allows the user to zoom in on the clicked location. * * @author Joachim Van der Auwera * @author Pieter De Graef */ public class PanController extends AbstractGraphicsController { private boolean zooming; private boolean panning; private boolean moving; private boolean showCursorOnMove; private Coordinate begin; private ZoomToRectangleController zoomToRectangleController; private Coordinate lastClickPosition; // Constructors: public PanController(MapWidget mapWidget) { super(mapWidget); zoomToRectangleController = new ZoomToRectangleController(mapWidget); } /** * Should the cursor only be shown when mouse is dragged (defaults to false) ? * * @return true if to be shown on drag */ public boolean isShowCursorOnMove() { return showCursorOnMove; } /** * If set to true, the move cursor is only shown when the mouse is dragged. * * @param showCursorOnMove * true if cursor should be shown on move (defaults to false) */ public void setShowCursorOnMove(boolean showCursorOnMove) { this.showCursorOnMove = showCursorOnMove; } @Override public void onDown(HumanInputEvent<?> event) { if (event.isControlKeyDown() || event.isShiftKeyDown()) { zooming = true; zoomToRectangleController.onDown(event); } else if (!isRightMouseButton(event)) { panning = true; mapWidget.getMapModel().getMapView().setPanDragging(true); begin = getLocation(event, RenderSpace.SCREEN); if (!isShowCursorOnMove()) { mapWidget.setCursor(Cursor.MOVE); } } lastClickPosition = getLocation(event, RenderSpace.WORLD); } @Override public void onUp(HumanInputEvent<?> event) { if (zooming) { zoomToRectangleController.onUp(event); zooming = false; } else if (panning) { stopPanning(event); } } @Override public void onDrag(HumanInputEvent<?> event) { if (zooming) { zoomToRectangleController.onDrag(event); } else if (panning) { if (!moving && isShowCursorOnMove()) { mapWidget.setCursor(Cursor.MOVE); } moving = true; updateView(event); } } @Override public void onMouseOut(MouseOutEvent event) { if (zooming) { zoomToRectangleController.onMouseOut(event); } else { stopPanning(null); } } /** * Zoom in to the double-clicked position. */ public void onDoubleClick(DoubleClickEvent event) { //Check if there was a last click that was handled in this class. if (null != lastClickPosition) { // Zoom in on the event location. Bbox bounds = mapWidget.getMapModel().getMapView().getBounds(); double x = lastClickPosition.getX() - (bounds.getWidth() / 4); double y = lastClickPosition.getY() - (bounds.getHeight() / 4); Bbox newBounds = new Bbox(x, y, bounds.getWidth() / 2, bounds.getHeight() / 2); mapWidget.getMapModel().getMapView().applyBounds(newBounds, ZoomOption.LEVEL_CHANGE); } } public boolean isMoving() { return moving; } // Private methods: private void stopPanning(HumanInputEvent<?> event) { mapWidget.getMapModel().getMapView().setPanDragging(false); panning = false; moving = false; mapWidget.setCursorString(mapWidget.getDefaultCursorString()); if (null != event) { updateView(event); } } private void updateView(HumanInputEvent<?> event) { Coordinate end = getLocation(event, RenderSpace.SCREEN); Coordinate beginWorld = getTransformer().viewToWorld(begin); Coordinate endWorld = getTransformer().viewToWorld(end); mapWidget.getMapModel().getMapView() .translate(beginWorld.getX() - endWorld.getX(), beginWorld.getY() - endWorld.getY()); begin = end; } @Override public void onDeactivate() { super.onDeactivate(); zoomToRectangleController.onDeactivate(); } }