package com.tyndalehouse.step; import android.content.Context; import android.graphics.Matrix; import android.graphics.PointF; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.ScaleGestureDetector.OnScaleGestureListener; import android.widget.Gallery; import android.widget.ImageView; public class FullGallery extends Gallery implements OnGestureListener, OnScaleGestureListener { private static final String TAG = "Gallery"; static final int NONE = 0; static final int DRAG = 1; int mode = NONE; private Context c; private ScaleGestureDetector mScaleDetector; private GestureDetector mDetector; private float mScaleFactor = 1.f; float new_distance_touch, old_distance_touch, init_x, init_y; Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); PointF mid = new PointF(); PointF start = new PointF(); ImageView imgPicture; public FullGallery(Context context, AttributeSet attrSet) { super(context, attrSet); c = context; mDetector = new GestureDetector(c,this); mScaleDetector = new ScaleGestureDetector(c, this); } @Override public boolean onTouchEvent(MotionEvent event) { //gesture detector for the movements imgPicture = (ImageView) super.getSelectedView(); if (mDetector.onTouchEvent(event)) { Log.d("onTouchEvent", "--[ MOVEMENT ]--"); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: init_x = event.getX(); init_y = event.getY(); midPoint(mid, event); savedMatrix.set(matrix); start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG" ); mode = DRAG; break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } break; } imgPicture = (ImageView) super.getSelectedView(); imgPicture.setImageMatrix(matrix); return true; } else if(mScaleDetector.onTouchEvent(event)) { // scale detector for zoom Log.d("onTouchEvent", "--[ SCALE ]--"); return true; } else return false; } public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); if (new_distance_touch > 10f) { matrix.set(savedMatrix); matrix.postScale(mScaleFactor, mScaleFactor, mid.x, mid.y); Log.d("ZOOMMING",matrix.toShortString()); } else { matrix.set(savedMatrix); matrix.postTranslate(init_x - start.x, init_y - start.y); Log.d("PANNING",matrix.toShortString()); } imgPicture.setImageMatrix(matrix); imgPicture.invalidate(); Log.d("MATRIX", matrix.toString()); return true; } //@Override public boolean onScaleBegin(ScaleGestureDetector detector) { Log.d(TAG, "-- onScaleBegin --"); matrix = imgPicture.getImageMatrix(); savedMatrix.set(matrix); start.set(init_x, init_y); return true; } //@Override public void onScaleEnd(ScaleGestureDetector detector) { Log.d(TAG, "-- onScaleEnd --"); old_distance_touch = detector.getPreviousSpan(); new_distance_touch = detector.getCurrentSpan(); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.d(TAG, "-- onFling --"); float velMax = 2500f; float velMin = 1000f; float velX = Math.abs(velocityX); if (velX > velMax) { velX = velMax; } else if (velX < velMin) { velX = velMin; } velX -= 600; int k = 500000; int speed = (int) Math.floor(1f / velX * k); setAnimationDuration(speed); int kEvent; if (isScrollingLeft(e1, e2)) { kEvent = KeyEvent.KEYCODE_DPAD_LEFT; } else { kEvent = KeyEvent.KEYCODE_DPAD_RIGHT; } onKeyDown(kEvent, null); return true; } private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2){ return e2.getX() > e1.getX(); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.d(TAG, "-- onScroll --"); return super.onScroll(e1, e2, distanceX, distanceY); } // private float spacing(MotionEvent event) { // float x = event.getX(0) - event.getX(1); // float y = event.getY(0) - event.getY(1); // return FloatMath.sqrt(x * x + y * y); // } // private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } }