11dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren/*
21dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * Copyright (C) 2013 The Android Open Source Project
31dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren *
41dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * Licensed under the Apache License, Version 2.0 (the "License");
51dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * you may not use this file except in compliance with the License.
61dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * You may obtain a copy of the License at
71dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren *
81dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren *      http://www.apache.org/licenses/LICENSE-2.0
91dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren *
101dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * Unless required by applicable law or agreed to in writing, software
111dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * distributed under the License is distributed on an "AS IS" BASIS,
121dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * See the License for the specific language governing permissions and
141dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * limitations under the License.
151dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren */
161dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wrenpackage com.android.dreams.phototable;
171dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
181dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wrenimport android.content.Context;
191dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wrenimport android.content.res.Resources;
201dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wrenimport android.view.MotionEvent;
211dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
221dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren/**
231dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren * Detect and dispatch edge events.
241dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren */
251dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wrenpublic class DragGestureDetector {
2688d80f4471c900628e2cb6eef23029b99af48e09Chris Wren    @SuppressWarnings("unused")
271dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private static final String TAG = "DragGestureDetector";
281dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
291dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private final PhotoTable mTable;
301dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private final float mTouchGain;
311dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
321dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private float[] mLast;
331dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private float[] mCurrent;
341dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private boolean mDrag;
351dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
361dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    public DragGestureDetector(Context context, PhotoTable table) {
371dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        Resources res = context.getResources();
381dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        mTouchGain = res.getInteger(R.integer.generalized_touch_gain) / 1000000f;
391dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        mTable = table;
401dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        mLast = new float[2];
411dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        mCurrent = new float[2];
421dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    }
431dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
441dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private void computeAveragePosition(MotionEvent event, float[] position) {
451dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        computeAveragePosition(event, position, -1);
461dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    }
471dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
481dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private void computeAveragePosition(MotionEvent event, float[] position, int ignore) {
491dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        final int pointerCount = event.getPointerCount();
501dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        position[0] = 0f;
511dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        position[1] = 0f;
521dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        float count = 0f;
531dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        for (int p = 0; p < pointerCount; p++) {
541dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            if (p != ignore) {
551dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                position[0] += event.getX(p);
561dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                position[1] += event.getY(p);
571dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                count += 1f;
581dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            }
591dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        }
601dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        position[0] /= count;
611dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        position[1] /= count;
621dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    }
631dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
641dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    public boolean onTouchEvent(MotionEvent event) {
651dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        int index = event.getActionIndex();
661dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        switch (event.getActionMasked()) {
671dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            case MotionEvent.ACTION_DOWN:
681dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                computeAveragePosition(event, mLast);
691dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                mDrag = false;
701dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                break;
711dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
721dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            case MotionEvent.ACTION_POINTER_DOWN:
731dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                mDrag = mTable.hasFocus();
741dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                computeAveragePosition(event, mLast);
751dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                break;
761dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
771dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            case MotionEvent.ACTION_POINTER_UP:
781dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                computeAveragePosition(event, mLast, index);
791dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                break;
801dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
811dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            case MotionEvent.ACTION_MOVE:
821dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                computeAveragePosition(event, mCurrent);
831dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                if (mDrag) {
841dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                    move(event, false);
851dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                }
861dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                break;
871dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
881dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            case MotionEvent.ACTION_CANCEL:
891dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            case MotionEvent.ACTION_UP:
901dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                if (mDrag) {
911dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                    move(event, true);
921dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                }
931dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                mDrag = false;
941dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                break;
951dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        }
961dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
971dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        if (mDrag) {
981dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren            mTable.refreshFocus();
991dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        }
1001dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
1011dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        return mDrag;
1021dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    }
1031dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
1041dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    private void move(MotionEvent event, boolean drop) {
10588d80f4471c900628e2cb6eef23029b99af48e09Chris Wren        mTable.move(mTable.getFocus(),
1061dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                mTouchGain * (mCurrent[0] - mLast[0]),
1071dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                mTouchGain * (mCurrent[1] - mLast[1]),
1081dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren                drop);
1091dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        mLast[0] = mCurrent[0];
1101dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren        mLast[1] = mCurrent[1];
1111dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren    }
1121dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren}
1131dc94b55d59f5c4dbf86788d0c32b7ac4449909aChris Wren
114