Package com.googlecode.mgwt.dom.client.recognizer.pinch

Source Code of com.googlecode.mgwt.dom.client.recognizer.pinch.PinchRecognizer

/*
* Copyright 2012 Daniel Kurka
*
* 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 com.googlecode.mgwt.dom.client.recognizer.pinch;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Touch;
import com.google.gwt.event.dom.client.TouchCancelEvent;
import com.google.gwt.event.dom.client.TouchEndEvent;
import com.google.gwt.event.dom.client.TouchMoveEvent;
import com.google.gwt.event.dom.client.TouchStartEvent;
import com.google.gwt.event.shared.HasHandlers;

import com.googlecode.mgwt.dom.client.event.touch.TouchCopy;
import com.googlecode.mgwt.dom.client.event.touch.TouchHandler;
import com.googlecode.mgwt.dom.client.recognizer.EventPropagator;

/**
* A PinchRecognizer tracks two finger on a screen that perform a zooming / pinching action
*
* @author Daniel Kurka
*
*/
public class PinchRecognizer implements TouchHandler {

  private static EventPropagator DEFAULT_EVENT_PROPAGATOR;

  private final HasHandlers source;

  private EventPropagator eventPropagator;

  private enum State {
    READY, INVALID, ONE_FINGER, TWO_FINGER;
  }

  private State state;

  private TouchCopy touchStart1;
  private TouchCopy touchStart2;

  private int touchCount;
  private double distance;

  private final OffsetProvider offsetProvider;

  /**
   * Construct a {@link PinchRecognizer}
   *
   * @param source the source to fire events on
   * @param offsetProvider the offset provider
   */
  public PinchRecognizer(HasHandlers source, OffsetProvider offsetProvider) {

    if (source == null) {
      throw new IllegalArgumentException("source can not be null");
    }
    if (offsetProvider == null) {
      throw new IllegalArgumentException("offsetProvider can not be null");
    }

    this.source = source;
    this.offsetProvider = offsetProvider;
    state = State.READY;
  }

  @Override
  public void onTouchStart(TouchStartEvent event) {
    touchCount++;
    switch (state) {
      case READY:
        touchStart1 = TouchCopy.copy(event.getTouches().get(0));
        state = State.ONE_FINGER;
        break;
      case ONE_FINGER:
        touchStart2 = TouchCopy.copy(event.getTouches().get(1));
        distance = (int) Math.sqrt(Math.pow(touchStart1.getPageX() - touchStart2.getPageX(), 2) + Math.pow(touchStart1.getPageY() - touchStart2.getPageY(), 2));
        state = State.TWO_FINGER;
        break;

      default:
        state = State.INVALID;
        break;
    }
  }

  @Override
  public void onTouchMove(TouchMoveEvent event) {
    switch (state) {
      case TWO_FINGER:

        Touch touch1 = event.getTouches().get(0);
        Touch touch2 = event.getTouches().get(1);

        int left = offsetProvider.getLeft();
        int top = offsetProvider.getTop();

        int x1 = touch1.getPageX() - left;
        int y1 = touch1.getPageY() - top;
        int x2 = touch2.getPageX() - left;
        int y2 = touch2.getPageY() - top;

        double newDistance = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
        int x = (x1 + x2) / 2;
        int y = (y1 + y2) / 2;

        getEventPropagator().fireEvent(source, new PinchEvent(x, y, distance / newDistance));
        distance = newDistance;

        break;

      default:
        state = State.INVALID;
        break;
    }
  }

  @Override
  public void onTouchEnd(TouchEndEvent event) {
    touchCount--;
    if (touchCount <= 0) {
      reset();
    } else {
      if (state == State.TWO_FINGER) {
        state = State.ONE_FINGER;
      } else {
        if (touchCount == 2) {
          state = State.TWO_FINGER;
        }
      }
    }
  }

  @Override
  public void onTouchCancel(TouchCancelEvent event) {
    touchCount--;
    if (touchCount <= 0) {
      reset();
    } else {
      if (state == State.TWO_FINGER) {
        state = State.ONE_FINGER;
      } else {
        if (touchCount == 2) {
          state = State.TWO_FINGER;
        }
      }
    }
  }

  private void reset() {
    touchCount = 0;
    state = State.READY;
  }

  // Visible for testing
  EventPropagator getEventPropagator() {
    if (eventPropagator == null) {
      if (DEFAULT_EVENT_PROPAGATOR == null) {
        DEFAULT_EVENT_PROPAGATOR = GWT.create(EventPropagator.class);
      }
      eventPropagator = DEFAULT_EVENT_PROPAGATOR;
    }
    return eventPropagator;
  }
}
TOP

Related Classes of com.googlecode.mgwt.dom.client.recognizer.pinch.PinchRecognizer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.