/* * Copyright (C) 2011 Virginia Tech Department of Computer Science * * 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. */ package sofia.internal.events; import android.graphics.Point; import android.graphics.PointF; import android.view.MotionEvent; import java.util.List; /** * Handles and dispatches the touch events. * * @author Brian Bowden */ public class TouchDispatcher { private static final EventDispatcher onTouchDown = new PointDispatcher("onTouchDown"); private static final EventDispatcher onScreenTouchDown = new PointDispatcher("onScreenTouchDown"); private static final EventDispatcher onTouchMove = new PointDispatcher("onTouchMove"); private static final EventDispatcher onScreenTouchMove = new PointDispatcher("onScreenTouchMove"); private static final EventDispatcher onTouchUp = new PointDispatcher("onTouchUp"); private static final EventDispatcher onScreenTouchUp = new PointDispatcher("onScreenTouchUp"); private static final EventDispatcher onTap = new PointDispatcher("onTap"); private static final EventDispatcher onScreenTap = new PointDispatcher("onScreenTap"); private static final EventDispatcher onDoubleTap = new PointDispatcher("onDoubleTap"); private static final EventDispatcher onScreenDoubleTap = new PointDispatcher("onScreenDoubleTap"); private TouchDispatcher() { // Nothing to do } /** * Determines which of the dispatchers to dispatch the event to. * * @param target object that is associated with the key event * @param e MotionEvent that is being checked */ public static void dispatchTo(Object target, MotionEvent e) { // FIXME PointF location = null; if (e != null) { // may need to fix later location = new PointF(e.getRawX() / 0.5f, e.getRawY() / 0.5f); } int action = e.getAction() & MotionEvent.ACTION_MASK; // Press if (action == MotionEvent.ACTION_DOWN) { onTouchDown.dispatch(target, location); onScreenTouchDown.dispatch(target, location); } // Move if (action == MotionEvent.ACTION_MOVE) { onTouchMove.dispatch(target, location); onScreenTouchMove.dispatch(target, location); } // Need to add support for double-tapping // Tap if (action == MotionEvent.ACTION_UP) { onTap.dispatch(target, location); //if (e.getClickCount() % 2 == 0) { onDoubleTap.dispatch(target, location); } onTouchUp.dispatch(target, location); } if (action == MotionEvent.ACTION_UP) { onScreenTap.dispatch(target, location); //if (e.getClickCount() % 2 == 0) { onScreenDoubleTap.dispatch(target, location); } onScreenTouchUp.dispatch(target, location); } } private static class PointDispatcher extends sofia.internal.events.EventDispatcher { //~ Constructors ...................................................... // ---------------------------------------------------------- public PointDispatcher(String method) { super(method); } //~ Protected methods ................................................. // ---------------------------------------------------------- @Override protected List<MethodTransformer> lookupTransformers( Object receiver, List<Class<?>> argTypes) { List<MethodTransformer> descriptors = super.lookupTransformers(receiver, argTypes); xyFloatTransformer.addIfSupportedBy(receiver, descriptors); xyIntTransformer.addIfSupportedBy(receiver, descriptors); pointTransformer.addIfSupportedBy(receiver, descriptors); emptyTransformer.addIfSupportedBy(receiver, descriptors); return descriptors; } // ---------------------------------------------------------- /** * Transforms an event with signature (PointF point) to one with * signature (float x, float y). */ private MethodTransformer xyFloatTransformer = new MethodTransformer(float.class, float.class) { // ---------------------------------------------------------- protected Object[] transform(Object... args) { PointF p = (PointF) args[0]; return new Object[] { p.x, p.y }; } }; // ---------------------------------------------------------- /** * Transforms an event with signature (PointF point) to one with * signature (int x, int y). */ private MethodTransformer xyIntTransformer = new MethodTransformer(int.class, int.class) { // ---------------------------------------------------------- protected Object[] transform(Object... args) { PointF p = (PointF) args[0]; return new Object[] { Math.round(p.x), Math.round(p.y) }; } }; // ---------------------------------------------------------- /** * Transforms an event with signature (PointF point) to one with * signature (Point p). */ private MethodTransformer pointTransformer = new MethodTransformer(Point.class) { // ---------------------------------------------------------- protected Object[] transform(Object... args) { PointF p = (PointF) args[0]; return new Object[] { new Point(Math.round(p.x), Math.round(p.y)) }; } }; // ---------------------------------------------------------- /** * Transforms an event with signature (PointF point) to one with * an empty signature. */ private MethodTransformer emptyTransformer = new MethodTransformer() { // ---------------------------------------------------------- protected Object[] transform(Object... args) { return NO_ARGS; } }; private static Object[] NO_ARGS = {}; } }