package ch.unifr.pai.twice.mousecontrol.client; /* * Copyright 2013 Oliver Schmid * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.util.Date; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.Touch; import com.google.gwt.event.dom.client.TouchEndEvent; import com.google.gwt.event.dom.client.TouchEndHandler; import com.google.gwt.event.dom.client.TouchMoveEvent; import com.google.gwt.event.dom.client.TouchMoveHandler; import com.google.gwt.event.dom.client.TouchStartEvent; import com.google.gwt.event.dom.client.TouchStartHandler; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.HTML; /** * The touchpad for mobile devices (based on scrolling for better performance). * * @author oli * */ public class TouchPadMobileWidget extends TouchPadWidget implements TouchStartHandler, TouchEndHandler, TouchMoveHandler { private int x; private int y; private boolean move; private boolean dragging = false; /** * Timer for recognizing a switch to drag mode */ private final Timer mouseDownTimer = new Timer() { @Override public void run() { down(true); downSent = true; dragging = true; if (isDoLog()) addToLog("startDrag", "cursorX=\"" + x + "\" cursorY=\"" + y + "\"", null); widget.getElement().setInnerHTML("<p>Your device is in dragging mode.</p><p> Tap on the screen to release.</p>"); } }; /** * Transform relative movements to absolute x- and y-coordinates * * @param dX * @param dY */ private void updatePos(int dX, int dY) { if (dX != 0) { int changeX = (int) Math.floor((dX * MOVEFACTOR)); x = Math.max(Math.min(x + changeX, screenWidth), 0); } if (dY != 0) { int changeY = (int) Math.floor((dY * MOVEFACTOR)); y = Math.max(Math.min(y + changeY, screenHeight), 0); } } private int lastX; private int lastY; private long fingerDownAt; private boolean downSent; DockLayoutPanel p = new DockLayoutPanel(Unit.PCT); // private MobileKeyboard keyboardButton = new MobileKeyboard("Keyboard", "Done"); HTML widget = new HTML(); public TouchPadMobileWidget() { super(false); widget.getElement().getStyle().setProperty("userSelect", "none"); widget.addTouchStartHandler(this); widget.addTouchEndHandler(this); widget.addTouchMoveHandler(this); widget.getElement().getStyle().setFontSize(20, Unit.PX); add(p); widget.setHeight("100%"); // p.addSouth(keyboardButton, 10); p.add(widget); // setWidgetTopBottom(widget, 0, Unit.PX, 0, Unit.PX); // setWidgetLeftRight(widget, 0, Unit.PX, 0, Unit.PX); } /* * (non-Javadoc) * @see ch.unifr.pai.twice.mousecontrol.client.TouchPadWidget#updateScreenDimensions() */ @Override protected void updateScreenDimensions() { } /* * (non-Javadoc) * @see ch.unifr.pai.twice.mousecontrol.client.TouchPadWidget#getX() */ @Override protected int getX() { return x; } /* * (non-Javadoc) * @see ch.unifr.pai.twice.mousecontrol.client.TouchPadWidget#getY() */ @Override protected int getY() { return y; } /** * On movement, calculate the new position of the mouse pointer on the shared screen * * @see com.google.gwt.event.dom.client.TouchMoveHandler#onTouchMove(com.google.gwt.event.dom.client.TouchMoveEvent) */ @Override public void onTouchMove(TouchMoveEvent event) { event.preventDefault(); event.stopPropagation(); if (event.getTouches().length() > 0) { Touch t = event.getTouches().get(0); int x = t.getClientX(); int y = t.getClientY(); int dX = x - lastX; int dY = y - lastY; if (Math.abs(dX) > MOVEMENTTHRESHOLD || Math.abs(dY) > MOVEMENTTHRESHOLD) { mouseDownTimer.cancel(); lastX = x; lastY = y; updatePos(dX, dY); move = true; } } } /** * On touch end - stop dragging * * @see com.google.gwt.event.dom.client.TouchEndHandler#onTouchEnd(com.google.gwt.event.dom.client.TouchEndEvent) */ @Override public void onTouchEnd(TouchEndEvent event) { event.preventDefault(); event.stopPropagation(); if (isDoLog()) addToLog("endTouch", "cursorX=\"" + x + "\" cursorY=\"" + y + "\"", null); if (fingerDownAt != -1) { if (!move) { stopDragging(); } } fingerDownAt = -1; move = false; } /* * (non-Javadoc) * @see ch.unifr.pai.twice.mousecontrol.client.TouchPadWidget#stopDragging() */ @Override protected void stopDragging() { if (!downSent) { down(true); mouseDownTimer.cancel(); } up(true); if (isDoLog()) addToLog("stopDrag", "cursorX=\"" + x + "\" cursorY=\"" + y + "\"", null); super.stopDragging(); widget.getElement().setInnerHTML(""); } /* * (non-Javadoc) * @see ch.unifr.pai.twice.mousecontrol.client.TouchPadWidget#stop() */ @Override public void stop() { if (dragging) { stopDragging(); } super.stop(); } /** * On touch start, check if it is the begin of a drag. * * @see com.google.gwt.event.dom.client.TouchStartHandler#onTouchStart(com.google.gwt.event.dom.client.TouchStartEvent) */ @Override public void onTouchStart(TouchStartEvent event) { event.preventDefault(); event.stopPropagation(); if (event.getTouches().length() > 0) { Touch t = event.getTouches().get(0); lastX = t.getClientX(); lastY = t.getClientY(); fingerDownAt = new Date().getTime(); if (isDoLog()) addToLog("startTouch", "cursorX=\"" + x + "\" cursorY=\"" + y + "\"", null); if (!move) { downSent = false; if (dragModeEnabled) mouseDownTimer.schedule(MOUSEDOWNTHRESHOLD); } } } }