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 
DragGestureDetector(Context context, PhotoTable table)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 
computeAveragePosition(MotionEvent event, float[] position)44     private void computeAveragePosition(MotionEvent event, float[] position) {
45         computeAveragePosition(event, position, -1);
46     }
47 
computeAveragePosition(MotionEvent event, float[] position, int ignore)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 
onTouchEvent(MotionEvent event)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 
move(MotionEvent event, boolean drop)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