/*
* 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 com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.dom.client.GestureChangeEvent;
import com.google.gwt.event.dom.client.GestureEndEvent;
import com.google.gwt.event.dom.client.GestureStartEvent;
import com.google.gwt.event.dom.client.HumanInputEvent;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseEvent;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.TouchCancelEvent;
import com.google.gwt.event.dom.client.TouchEndEvent;
import com.google.gwt.event.dom.client.TouchEvent;
import com.google.gwt.event.dom.client.TouchMoveEvent;
import com.google.gwt.event.dom.client.TouchStartEvent;
import org.geomajas.annotation.Api;
import org.geomajas.geometry.Coordinate;
import org.geomajas.gwt.client.event.PointerTouchCancelEvent;
import org.geomajas.gwt.client.event.PointerTouchEndEvent;
import org.geomajas.gwt.client.event.PointerTouchMoveEvent;
import org.geomajas.gwt.client.event.PointerTouchStartEvent;
import org.geomajas.gwt.client.handler.MapDownHandler;
import org.geomajas.gwt.client.handler.MapDragHandler;
import org.geomajas.gwt.client.handler.MapTouchHandler;
import org.geomajas.gwt.client.handler.MapUpHandler;
import org.geomajas.gwt.client.map.RenderSpace;
/**
* <p> Base implementation of the {@link Controller} interface that tries to align mouse and touch behavior. It does
* this by providing extra methods through the {@link MapDownHandler}, {@link MapUpHandler} and {@link MapDragHandler}
* interfaces. When using this class a base (which is recommended), you can chose whether to support mouse events only,
* touch events only or both simultaneously. </p> <p> In short, here are your three options: <ul> <li>Supporting mouse
* events only: Override the mouse handler methods (onMouseDown, onMouseUp, ....)</li> <li>Supporting touch events only:
* Override the touch handler methods (onTouchStart, onTouchMove, ...)</li> <li>Supporting both (recommended): Override
* the onDown, onUp and onDrag methods. By default both the onMouseDown and the onTouchStart will invoke the onDown
* method. The same goes for the onUp and onDrag. So by implementing those methods you will have both mobile and desktop
* support.</li> </ul> </p> <p> One extra note to point out is that by default the touch event methods will stop any
* further propagation and prevent the default behavior of the events. This is done because, by default, browsers on
* mobile devices tend to scroll all over the place - creating unwanted behavior. </p>
*
* @author Pieter De Graef
* @since 2.0.0
*/
@Api(allMethods = true)
public abstract class AbstractController implements Controller, MapDownHandler, MapUpHandler, MapDragHandler,
MapTouchHandler {
protected boolean dragging;
protected MapEventParser eventParser;
// ------------------------------------------------------------------------
// Constructors:
// ------------------------------------------------------------------------
/**
* Construct controller.
*
* @param dragging are we dragging?
*/
public AbstractController(boolean dragging) {
this.dragging = dragging;
}
/**
* Construact controller.
*
* @param eventParser event parser
* @param dragging are we dragging
*/
public AbstractController(MapEventParser eventParser, boolean dragging) {
this.dragging = dragging;
this.eventParser = eventParser;
}
// ------------------------------------------------------------------------
// MapEventParser implementation:
// ------------------------------------------------------------------------
@Override
public Coordinate getLocation(HumanInputEvent<?> event, RenderSpace renderSpace) {
return eventParser.getLocation(event, renderSpace);
}
@Override
public Element getTarget(HumanInputEvent<?> event) {
return eventParser.getTarget(event);
}
protected void setMapEventParser(MapEventParser eventParser) {
this.eventParser = eventParser;
}
@Override
public boolean isRightMouseButton(HumanInputEvent<?> event) {
if (event instanceof MouseEvent<?>) {
return ((MouseEvent<?>) event).getNativeButton() == NativeEvent.BUTTON_RIGHT;
}
return false;
}
// ------------------------------------------------------------------------
// Methods for aligning mouse and touch events for dragging :
// ------------------------------------------------------------------------
@Override
public void onDown(HumanInputEvent<?> event) {
}
@Override
public void onUp(HumanInputEvent<?> event) {
}
@Override
public void onDrag(HumanInputEvent<?> event) {
}
/**
* @todo javadoc unknown.
*/
public boolean isDragging() {
return dragging;
}
// ------------------------------------------------------------------------
// Methods for aligning mouse and touch events (general case) :
// ------------------------------------------------------------------------
/**
* Forward as mouse down and stop the event.
* @since 2.4.0
*/
@Override
public void onMapTouchStart(TouchEvent<?> event) {
onDown(event);
event.stopPropagation();
event.preventDefault();
}
/**
* Forward as mouse move and stop the event.
* @since 2.4.0
*/
@Override
public void onMapTouchMove(TouchEvent<?> event) {
onDrag(event);
event.stopPropagation();
event.preventDefault();
}
/**
* Forward as mouse up and stop the event.
* @since 2.4.0
*/
@Override
public void onMapTouchEnd(TouchEvent<?> event) {
onUp(event);
event.stopPropagation();
event.preventDefault();
}
/**
* Forward as mouse up and stop the event.
* @since 2.4.0
*/
@Override
public void onMapTouchCancel(TouchEvent<?> event) {
onUp(event);
event.stopPropagation();
event.preventDefault();
}
// ------------------------------------------------------------------------
// Mouse Handler implementations:
// ------------------------------------------------------------------------
@Override
public void onMouseDown(MouseDownEvent event) {
dragging = true;
onDown(event);
}
@Override
public void onMouseUp(MouseUpEvent event) {
dragging = false;
onUp(event);
}
@Override
public void onMouseMove(MouseMoveEvent event) {
if (dragging) {
onDrag(event);
}
}
@Override
public void onMouseOut(MouseOutEvent event) {
}
@Override
public void onMouseOver(MouseOverEvent event) {
}
@Override
public void onMouseWheel(MouseWheelEvent event) {
}
@Override
public void onDoubleClick(DoubleClickEvent event) {
}
// ------------------------------------------------------------------------
// Touch Handler implementations:
// ------------------------------------------------------------------------
/**
* Don't override this method, override {@link #onMapTouchStart(TouchEvent)} instead.
*/
@Override
public void onTouchStart(TouchStartEvent event) {
onMapTouchStart(event);
}
/**
* Don't override this method, override {@link #onMapTouchMove(TouchEvent)} instead.
*/
@Override
public void onTouchMove(TouchMoveEvent event) {
onMapTouchMove(event);
}
/**
* Don't override this method, override {@link #onMapTouchEnd(TouchEvent)} instead.
*/
@Override
public void onTouchEnd(TouchEndEvent event) {
onMapTouchEnd(event);
}
/**
* Don't override this method, override {@link #onMapTouchCancel(TouchEvent)} instead.
*/
@Override
public void onTouchCancel(TouchCancelEvent event) {
onMapTouchCancel(event);
}
// ------------------------------------------------------------------------
// Pointer Touch Handler implementations:
// ------------------------------------------------------------------------
/**
* Don't override this method, override {@link #onMapTouchStart(TouchEvent)} instead.
* @since 2.4.0
*/
@Override
public void onPointerTouchStart(PointerTouchStartEvent event) {
onMapTouchStart(event);
}
/**
* Don't override this method, override {@link #onMapTouchMove(TouchEvent)} instead.
* @since 2.4.0
*/
@Override
public void onPointerTouchMove(PointerTouchMoveEvent event) {
onMapTouchMove(event);
}
/**
* Don't override this method, override {@link #onMapTouchEnd(TouchEvent)} instead.
* @since 2.4.0
*/
@Override
public void onPointerTouchEnd(PointerTouchEndEvent event) {
onMapTouchEnd(event);
}
/**
* Don't override this method, override {@link #onMapTouchCancel(TouchEvent)} instead.
* @since 2.4.0
*/
@Override
public void onPointerTouchCancel(PointerTouchCancelEvent event) {
onMapTouchCancel(event);
}
// ------------------------------------------------------------------------
// Gesture Handler implementations:
// ------------------------------------------------------------------------
@Override
public void onGestureStart(GestureStartEvent event) {
}
@Override
public void onGestureChange(GestureChangeEvent event) {
}
@Override
public void onGestureEnd(GestureEndEvent event) {
}
}