Пример #1
0
  private void track(MotionEvent event) {
    mX.saveTouchPos();
    mY.saveTouchPos();

    for (int i = 0; i < event.getHistorySize(); i++) {
      track(
          event.getHistoricalX(0, i), event.getHistoricalY(0, i), event.getHistoricalEventTime(i));
    }
    track(event.getX(0), event.getY(0), event.getEventTime());

    if (stopped()) {
      if (mState == PanZoomState.PANNING) {
        setState(PanZoomState.PANNING_HOLD);
      } else if (mState == PanZoomState.PANNING_LOCKED) {
        setState(PanZoomState.PANNING_HOLD_LOCKED);
      } else {
        // should never happen, but handle anyway for robustness
        Log.e(LOGTAG, "Impossible case " + mState + " when stopped in track");
        setState(PanZoomState.PANNING_HOLD_LOCKED);
      }
    }

    mX.startPan();
    mY.startPan();
    updatePosition();
  }
Пример #2
0
 /** This function must be called from the UI thread. */
 public void abortAnimation() {
   checkMainThread();
   // this happens when gecko changes the viewport on us or if the device is rotated.
   // if that's the case, abort any animation in progress and re-zoom so that the page
   // snaps to edges. for other cases (where the user's finger(s) are down) don't do
   // anything special.
   switch (mState) {
     case FLING:
       mX.stopFling();
       mY.stopFling();
       // fall through
     case BOUNCE:
     case ANIMATED_ZOOM:
       // the zoom that's in progress likely makes no sense any more (such as if
       // the screen orientation changed) so abort it
       setState(PanZoomState.NOTHING);
       // fall through
     case NOTHING:
       // Don't do animations here; they're distracting and can cause flashes on page
       // transitions.
       synchronized (mTarget.getLock()) {
         mTarget.setViewportMetrics(getValidViewportMetrics());
       }
       break;
   }
 }
Пример #3
0
  private void fling() {
    updatePosition();

    stopAnimationTimer();

    boolean stopped = stopped();
    mX.startFling(stopped);
    mY.startFling(stopped);

    startAnimationTimer(new FlingRunnable());
  }
Пример #4
0
  private void track(float x, float y, long time) {
    float timeDelta = (float) (time - mLastEventTime);
    if (FloatUtils.fuzzyEquals(timeDelta, 0)) {
      // probably a duplicate event, ignore it. using a zero timeDelta will mess
      // up our velocity
      return;
    }
    mLastEventTime = time;

    mX.updateWithTouchAt(x, timeDelta);
    mY.updateWithTouchAt(y, timeDelta);
  }
Пример #5
0
 private void updatePosition() {
   mX.displace();
   mY.displace();
   PointF displacement = resetDisplacement();
   if (FloatUtils.fuzzyEquals(displacement.x, 0.0f)
       && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
     return;
   }
   if (!mSubscroller.scrollBy(displacement)) {
     synchronized (mTarget.getLock()) {
       scrollBy(displacement.x, displacement.y);
     }
   }
 }
Пример #6
0
  public PanZoomController(PanZoomTarget target, EventDispatcher eventDispatcher) {
    mTarget = target;
    mSubscroller = new SubdocumentScrollHelper(this, eventDispatcher);
    mX = new AxisX(mSubscroller);
    mY = new AxisY(mSubscroller);

    mMainThread = GeckoApp.mAppContext.getMainLooper().getThread();
    checkMainThread();

    setState(PanZoomState.NOTHING);

    mEventDispatcher = eventDispatcher;
    registerEventListener(MESSAGE_ZOOM_RECT);
    registerEventListener(MESSAGE_ZOOM_PAGE);

    Axis.initPrefs();
  }
Пример #7
0
  private void startPanning(float x, float y, long time) {
    float dx = mX.panDistance(x);
    float dy = mY.panDistance(y);
    double angle = Math.atan2(dy, dx); // range [-pi, pi]
    angle = Math.abs(angle); // range [0, pi]

    // When the touch move breaks through the pan threshold, reposition the touch down origin
    // so the page won't jump when we start panning.
    mX.startTouch(x);
    mY.startTouch(y);
    mLastEventTime = time;

    if (!mX.scrollable() || !mY.scrollable()) {
      setState(PanZoomState.PANNING);
    } else if (angle < AXIS_LOCK_ANGLE || angle > (Math.PI - AXIS_LOCK_ANGLE)) {
      mY.setScrollingDisabled(true);
      setState(PanZoomState.PANNING_LOCKED);
    } else if (Math.abs(angle - (Math.PI / 2)) < AXIS_LOCK_ANGLE) {
      mX.setScrollingDisabled(true);
      setState(PanZoomState.PANNING_LOCKED);
    } else {
      setState(PanZoomState.PANNING);
    }
  }
Пример #8
0
  @Override
  public boolean onScale(SimpleScaleGestureDetector detector) {
    if (GeckoApp.mAppContext == null || GeckoApp.mAppContext.mDOMFullScreen) return false;

    if (mState != PanZoomState.PINCHING) return false;

    float prevSpan = detector.getPreviousSpan();
    if (FloatUtils.fuzzyEquals(prevSpan, 0.0f)) {
      // let's eat this one to avoid setting the new zoom to infinity (bug 711453)
      return true;
    }

    float spanRatio = detector.getCurrentSpan() / prevSpan;

    /*
     * Apply edge resistance if we're zoomed out smaller than the page size by scaling the zoom
     * factor toward 1.0.
     */
    float resistance = Math.min(mX.getEdgeResistance(true), mY.getEdgeResistance(true));
    if (spanRatio > 1.0f) spanRatio = 1.0f + (spanRatio - 1.0f) * resistance;
    else spanRatio = 1.0f - (1.0f - spanRatio) * resistance;

    synchronized (mTarget.getLock()) {
      float newZoomFactor = getMetrics().zoomFactor * spanRatio;
      float minZoomFactor = 0.0f;
      float maxZoomFactor = MAX_ZOOM;

      ZoomConstraints constraints = mTarget.getZoomConstraints();

      if (constraints.getMinZoom() > 0) minZoomFactor = constraints.getMinZoom();
      if (constraints.getMaxZoom() > 0) maxZoomFactor = constraints.getMaxZoom();

      if (newZoomFactor < minZoomFactor) {
        // apply resistance when zooming past minZoomFactor,
        // such that it asymptotically reaches minZoomFactor / 2.0
        // but never exceeds that
        final float rate = 0.5f; // controls how quickly we approach the limit
        float excessZoom = minZoomFactor - newZoomFactor;
        excessZoom = 1.0f - (float) Math.exp(-excessZoom * rate);
        newZoomFactor = minZoomFactor * (1.0f - excessZoom / 2.0f);
      }

      if (newZoomFactor > maxZoomFactor) {
        // apply resistance when zooming past maxZoomFactor,
        // such that it asymptotically reaches maxZoomFactor + 1.0
        // but never exceeds that
        float excessZoom = newZoomFactor - maxZoomFactor;
        excessZoom = 1.0f - (float) Math.exp(-excessZoom);
        newZoomFactor = maxZoomFactor + excessZoom;
      }

      scrollBy(mLastZoomFocus.x - detector.getFocusX(), mLastZoomFocus.y - detector.getFocusY());
      PointF focus = new PointF(detector.getFocusX(), detector.getFocusY());
      scaleWithFocus(newZoomFactor, focus);
    }

    mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY());

    GeckoEvent event =
        GeckoEvent.createNativeGestureEvent(
            GeckoEvent.ACTION_MAGNIFY, mLastZoomFocus, getMetrics().zoomFactor);
    GeckoAppShell.sendEventToGecko(event);

    return true;
  }
Пример #9
0
 PointF resetDisplacement() {
   return new PointF(mX.resetDisplacement(), mY.resetDisplacement());
 }
Пример #10
0
 public PointF getVelocityVector() {
   return new PointF(mX.getRealVelocity(), mY.getRealVelocity());
 }
Пример #11
0
 private float getVelocity() {
   float xvel = mX.getRealVelocity();
   float yvel = mY.getRealVelocity();
   return FloatMath.sqrt(xvel * xvel + yvel * yvel);
 }
Пример #12
0
 private float panDistance(MotionEvent move) {
   float dx = mX.panDistance(move.getX(0));
   float dy = mY.panDistance(move.getY(0));
   return FloatMath.sqrt(dx * dx + dy * dy);
 }
Пример #13
0
 private void startTouch(float x, float y, long time) {
   mX.startTouch(x);
   mY.startTouch(y);
   setState(PanZoomState.TOUCHING);
   mLastEventTime = time;
 }
Пример #14
0
 public int getOverScrollMode() {
   return mX.getOverScrollMode();
 }
Пример #15
0
 public void setOverScrollMode(int overscrollMode) {
   mX.setOverScrollMode(overscrollMode);
   mY.setOverScrollMode(overscrollMode);
 }