content: package com.termux.view;
  
  import android.content.Context;
  import android.view.GestureDetector;
  import android.view.MotionEvent;
  import android.view.ScaleGestureDetector;
  
  /** A combination of {@link GestureDetector} and {@link ScaleGestureDetector}. */
  final class GestureAndScaleRecognizer {
  
      public interface Listener {
          boolean onSingleTapUp(MotionEvent e);
  
          boolean onDoubleTap(MotionEvent e);
  
          boolean onScroll(MotionEvent e2, float dx, float dy);
  
          boolean onFling(MotionEvent e, float velocityX, float velocityY);
  
          boolean onScale(float focusX, float focusY, float scale);
  
          boolean onDown(float x, float y);
  
          boolean onUp(MotionEvent e);
  
          void onLongPress(MotionEvent e);
      }
  
      private final GestureDetector mGestureDetector;
      private final ScaleGestureDetector mScaleDetector;
      final Listener mListener;
      boolean isAfterLongPress;
  
      public GestureAndScaleRecognizer(Context context, Listener listener) {
          mListener = listener;
  
          mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
              @Override
              public boolean onScroll(MotionEvent e1, MotionEvent e2, float dx, float dy) {
                  return mListener.onScroll(e2, dx, dy);
              }
  
              @Override
              public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                  return mListener.onFling(e2, velocityX, velocityY);
              }
  
              @Override
              public boolean onDown(MotionEvent e) {
                  return mListener.onDown(e.getX(), e.getY());
              }
  
              @Override
              public void onLongPress(MotionEvent e) {
                  mListener.onLongPress(e);
                  isAfterLongPress = true;
              }
          }, null, true /* ignoreMultitouch */);
  
          mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
              @Override
              public boolean onSingleTapConfirmed(MotionEvent e) {
                  return mListener.onSingleTapUp(e);
              }
  
              @Override
              public boolean onDoubleTap(MotionEvent e) {
                  return mListener.onDoubleTap(e);
              }
  
              @Override
              public boolean onDoubleTapEvent(MotionEvent e) {
                  return true;
              }
          });
  
          mScaleDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
              @Override
              public boolean onScaleBegin(ScaleGestureDetector detector) {
                  return true;
              }
  
              @Override
              public boolean onScale(ScaleGestureDetector detector) {
                  return mListener.onScale(detector.getFocusX(), detector.getFocusY(), detector.getScaleFactor());
              }
          });
          mScaleDetector.setQuickScaleEnabled(false);
      }
  
      public void onTouchEvent(MotionEvent event) {
          mGestureDetector.onTouchEvent(event);
          mScaleDetector.onTouchEvent(event);
          switch (event.getAction()) {
              case MotionEvent.ACTION_DOWN:
                  isAfterLongPress = false;
                  break;
              case MotionEvent.ACTION_UP:
                  if (!isAfterLongPress) {
                      // This behaviour is desired when in e.g. vim with mouse events, where we do not
                      // want to move the cursor when lifting finger after a long press.
                      mListener.onUp(event);
                  }
                  break;
          }
      }
  
      public boolean isInProgress() {
          return mScaleDetector.isInProgress();
      }
  
  }
  