1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.dreams.phototable; 17 18 import android.content.Context; 19 import android.content.res.Resources; 20 import android.view.MotionEvent; 21 22 /** 23 * Detect and dispatch edge events. 24 */ 25 public class DragGestureDetector { 26 @SuppressWarnings("unused") 27 private static final String TAG = "DragGestureDetector"; 28 29 private final PhotoTable mTable; 30 private final float mTouchGain; 31 32 private float[] mLast; 33 private float[] mCurrent; 34 private boolean mDrag; 35 36 public DragGestureDetector(Context context, PhotoTable table) { 37 Resources res = context.getResources(); 38 mTouchGain = res.getInteger(R.integer.generalized_touch_gain) / 1000000f; 39 mTable = table; 40 mLast = new float[2]; 41 mCurrent = new float[2]; 42 } 43 44 private void computeAveragePosition(MotionEvent event, float[] position) { 45 computeAveragePosition(event, position, -1); 46 } 47 48 private void computeAveragePosition(MotionEvent event, float[] position, int ignore) { 49 final int pointerCount = event.getPointerCount(); 50 position[0] = 0f; 51 position[1] = 0f; 52 float count = 0f; 53 for (int p = 0; p < pointerCount; p++) { 54 if (p != ignore) { 55 position[0] += event.getX(p); 56 position[1] += event.getY(p); 57 count += 1f; 58 } 59 } 60 position[0] /= count; 61 position[1] /= count; 62 } 63 64 public boolean onTouchEvent(MotionEvent event) { 65 int index = event.getActionIndex(); 66 switch (event.getActionMasked()) { 67 case MotionEvent.ACTION_DOWN: 68 computeAveragePosition(event, mLast); 69 mDrag = false; 70 break; 71 72 case MotionEvent.ACTION_POINTER_DOWN: 73 mDrag = mTable.hasFocus(); 74 computeAveragePosition(event, mLast); 75 break; 76 77 case MotionEvent.ACTION_POINTER_UP: 78 computeAveragePosition(event, mLast, index); 79 break; 80 81 case MotionEvent.ACTION_MOVE: 82 computeAveragePosition(event, mCurrent); 83 if (mDrag) { 84 move(event, false); 85 } 86 break; 87 88 case MotionEvent.ACTION_CANCEL: 89 case MotionEvent.ACTION_UP: 90 if (mDrag) { 91 move(event, true); 92 } 93 mDrag = false; 94 break; 95 } 96 97 if (mDrag) { 98 mTable.refreshFocus(); 99 } 100 101 return mDrag; 102 } 103 104 private void move(MotionEvent event, boolean drop) { 105 mTable.move(mTable.getFocus(), 106 mTouchGain * (mCurrent[0] - mLast[0]), 107 mTouchGain * (mCurrent[1] - mLast[1]), 108 drop); 109 mLast[0] = mCurrent[0]; 110 mLast[1] = mCurrent[1]; 111 } 112 } 113 114