14d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb/*
24d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * Copyright (C) 2012 The Android Open Source Project
34d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb *
44d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
54d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * you may not use this file except in compliance with the License.
64d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * You may obtain a copy of the License at
74d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb *
84d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
94d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb *
104d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * Unless required by applicable law or agreed to in writing, software
114d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
124d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * See the License for the specific language governing permissions and
144d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb * limitations under the License.
154d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb */
164d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
174d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbpackage com.android.camera;
184d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
194d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport android.os.Handler;
204d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport android.os.Message;
21571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolbimport android.util.Log;
224d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport android.view.MotionEvent;
234d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport android.view.ScaleGestureDetector;
24571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolbimport android.view.View;
254d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport android.view.ViewConfiguration;
264d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
274d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport com.android.camera.ui.PieRenderer;
284d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport com.android.camera.ui.RenderOverlay;
294d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbimport com.android.camera.ui.ZoomRenderer;
304d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
31571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolbimport java.util.ArrayList;
32571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolbimport java.util.List;
33571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb
344d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolbpublic class PreviewGestures
354d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        implements ScaleGestureDetector.OnScaleGestureListener {
364d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
374d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private static final String TAG = "CAM_gestures";
384d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
394d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private static final long TIMEOUT_PIE = 200;
404d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private static final int MSG_PIE = 1;
414d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private static final int MODE_NONE = 0;
424d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private static final int MODE_PIE = 1;
434d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private static final int MODE_ZOOM = 2;
44571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    private static final int MODE_MODULE = 3;
454d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private static final int MODE_ALL = 4;
464d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
474d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private CameraActivity mActivity;
48571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    private CameraModule mModule;
494d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private RenderOverlay mOverlay;
504d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private PieRenderer mPie;
514d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private ZoomRenderer mZoom;
524d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private MotionEvent mDown;
53ba7bb98f7550adee1aa99419bda412948a413fb9Michael Kolb    private MotionEvent mCurrent;
544d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private ScaleGestureDetector mScale;
55571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    private List<View> mReceivers;
564d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private int mMode;
574d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private int mSlop;
584d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private int mTapTimeout;
594d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private boolean mEnabled;
604d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private boolean mZoomOnly;
611cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb    private int mOrientation;
62b1ddf5700f9e3950cead691cab57c4bbf03e577dMichael Kolb    private int[] mLocation;
63b1ddf5700f9e3950cead691cab57c4bbf03e577dMichael Kolb
644d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private Handler mHandler = new Handler() {
654d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        public void handleMessage(Message msg) {
664d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            if (msg.what == MSG_PIE) {
674d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                mMode = MODE_PIE;
684d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                openPie();
694d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                cancelActivityTouchHandling(mDown);
704d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            }
714d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        }
724d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    };
734d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
74571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    public PreviewGestures(CameraActivity ctx, CameraModule module,
75471c997edfddccfa0762fa720c82cc95777584e8John Reck            ZoomRenderer zoom, PieRenderer pie) {
764d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mActivity = ctx;
77571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        mModule = module;
784d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mPie = pie;
794d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mZoom = zoom;
804d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mMode = MODE_ALL;
814d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mScale = new ScaleGestureDetector(ctx, this);
824d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mSlop = (int) ctx.getResources().getDimension(R.dimen.pie_touch_slop);
834d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mTapTimeout = ViewConfiguration.getTapTimeout();
844d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mEnabled = true;
85b1ddf5700f9e3950cead691cab57c4bbf03e577dMichael Kolb        mLocation = new int[2];
864d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
874d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
88471c997edfddccfa0762fa720c82cc95777584e8John Reck    public void setRenderOverlay(RenderOverlay overlay) {
89471c997edfddccfa0762fa720c82cc95777584e8John Reck        mOverlay = overlay;
90471c997edfddccfa0762fa720c82cc95777584e8John Reck    }
91471c997edfddccfa0762fa720c82cc95777584e8John Reck
921cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb    public void setOrientation(int orientation) {
931cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        mOrientation = orientation;
941cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb    }
951cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb
964d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public void setEnabled(boolean enabled) {
974d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mEnabled = enabled;
984d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        if (!enabled) {
994d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            cancelPie();
1004d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        }
1014d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
1024d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
1034d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public void setZoomOnly(boolean zoom) {
10442e5d98096a1bc32660d08f4e984023df8cd147bMichael Kolb        mZoomOnly = zoom;
1054d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
1064d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
107571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    public void addTouchReceiver(View v) {
108571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        if (mReceivers == null) {
109571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb            mReceivers = new ArrayList<View>();
110571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        }
111571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        mReceivers.add(v);
112571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    }
113571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb
114471c997edfddccfa0762fa720c82cc95777584e8John Reck    public void clearTouchReceivers() {
115471c997edfddccfa0762fa720c82cc95777584e8John Reck        if (mReceivers != null) {
116471c997edfddccfa0762fa720c82cc95777584e8John Reck            mReceivers.clear();
117471c997edfddccfa0762fa720c82cc95777584e8John Reck        }
118471c997edfddccfa0762fa720c82cc95777584e8John Reck    }
119471c997edfddccfa0762fa720c82cc95777584e8John Reck
1204d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public boolean dispatchTouch(MotionEvent m) {
1214d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        if (!mEnabled) {
1224d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            return mActivity.superDispatchTouchEvent(m);
1234d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        }
124ba7bb98f7550adee1aa99419bda412948a413fb9Michael Kolb        mCurrent = m;
1254d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        if (MotionEvent.ACTION_DOWN == m.getActionMasked()) {
126571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb            if (checkReceivers(m)) {
127571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                mMode = MODE_MODULE;
128571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                return mActivity.superDispatchTouchEvent(m);
129571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb            } else {
130571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                mMode = MODE_ALL;
131571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                mDown = MotionEvent.obtain(m);
13255f0d13040df45c75704df9d633b444cb36f2465Michael Kolb                if (mPie != null && mPie.showsItems()) {
13355f0d13040df45c75704df9d633b444cb36f2465Michael Kolb                    mMode = MODE_PIE;
13455f0d13040df45c75704df9d633b444cb36f2465Michael Kolb                    return sendToPie(m);
13555f0d13040df45c75704df9d633b444cb36f2465Michael Kolb                }
136571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                if (mPie != null && !mZoomOnly) {
137571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                    mHandler.sendEmptyMessageDelayed(MSG_PIE, TIMEOUT_PIE);
138571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                }
139571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                if (mZoom != null) {
140571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                    mScale.onTouchEvent(m);
141571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                }
142571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                // make sure this is ok
143571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                return mActivity.superDispatchTouchEvent(m);
1444d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            }
1454d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        } else if (mMode == MODE_NONE) {
14664f033efe1b4c00b1e532a352f28f91a28055514Michael Kolb            return false;
1474d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        } else if (mMode == MODE_PIE) {
148e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb            if (MotionEvent.ACTION_POINTER_DOWN == m.getActionMasked()) {
149e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb                sendToPie(makeCancelEvent(m));
150e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb                if (mZoom != null) {
151e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb                    onScaleBegin(mScale);
152e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb                }
153e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb            } else {
154e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb                return sendToPie(m);
155e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb            }
156e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb            return true;
157999eb5f1da387786883150953930f88274ca9ffeMichael Kolb        } else if (mMode == MODE_ZOOM) {
158999eb5f1da387786883150953930f88274ca9ffeMichael Kolb            mScale.onTouchEvent(m);
159999eb5f1da387786883150953930f88274ca9ffeMichael Kolb            if (!mScale.isInProgress() && MotionEvent.ACTION_POINTER_UP == m.getActionMasked()) {
160999eb5f1da387786883150953930f88274ca9ffeMichael Kolb                mMode = MODE_NONE;
161999eb5f1da387786883150953930f88274ca9ffeMichael Kolb                onScaleEnd(mScale);
162999eb5f1da387786883150953930f88274ca9ffeMichael Kolb            }
163999eb5f1da387786883150953930f88274ca9ffeMichael Kolb            return true;
164571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        } else if (mMode == MODE_MODULE) {
16564f033efe1b4c00b1e532a352f28f91a28055514Michael Kolb            return mActivity.superDispatchTouchEvent(m);
1664d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        } else {
167b30f0c4cb5aa6eec6dccc879bfc9d6a4c3fd0eccMangesh Ghiware            // didn't receive down event previously;
168b30f0c4cb5aa6eec6dccc879bfc9d6a4c3fd0eccMangesh Ghiware            // assume module wasn't initialzed and ignore this event.
169b30f0c4cb5aa6eec6dccc879bfc9d6a4c3fd0eccMangesh Ghiware            if (mDown == null) {
170b30f0c4cb5aa6eec6dccc879bfc9d6a4c3fd0eccMangesh Ghiware                return true;
171b30f0c4cb5aa6eec6dccc879bfc9d6a4c3fd0eccMangesh Ghiware            }
1724d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            if (MotionEvent.ACTION_POINTER_DOWN == m.getActionMasked()) {
1737a6696dbdd858e07319b3981a405c575460fde3bMichael Kolb                if (!mZoomOnly) {
1744d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                    cancelPie();
175999eb5f1da387786883150953930f88274ca9ffeMichael Kolb                    sendToPie(makeCancelEvent(m));
1764d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                }
1770f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb                if (mZoom != null) {
178999eb5f1da387786883150953930f88274ca9ffeMichael Kolb                    mScale.onTouchEvent(m);
1790f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb                    onScaleBegin(mScale);
1800f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb                }
1810f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb            } else if ((mMode == MODE_ZOOM) && !mScale.isInProgress()
1820f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb                    && MotionEvent.ACTION_POINTER_UP == m.getActionMasked()) {
1830f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb                // user initiated and stopped zoom gesture without zooming
184999eb5f1da387786883150953930f88274ca9ffeMichael Kolb                mScale.onTouchEvent(m);
1850f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb                onScaleEnd(mScale);
1867a6696dbdd858e07319b3981a405c575460fde3bMichael Kolb            }
1877a6696dbdd858e07319b3981a405c575460fde3bMichael Kolb            // not zoom or pie mode and no timeout yet
1884d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            if (mZoom != null) {
1894d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                boolean res = mScale.onTouchEvent(m);
1904d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                if (mScale.isInProgress()) {
1914d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                    cancelPie();
1924d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                    cancelActivityTouchHandling(m);
1934d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                    return res;
1944d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                }
1954d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            }
1964d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            if (MotionEvent.ACTION_UP == m.getActionMasked()) {
1974d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                cancelPie();
1984d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                cancelActivityTouchHandling(m);
199571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                // must have been tap
200571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                if (m.getEventTime() - mDown.getEventTime() < mTapTimeout) {
2018042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb                    mModule.onSingleTapUp(null,
2028042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb                            (int) mDown.getX() - mOverlay.getWindowPositionX(),
2038042e7045f3e11dd49d40eebe603eb5fe12d711aMichael Kolb                            (int) mDown.getY() - mOverlay.getWindowPositionY());
2044d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                    return true;
2054d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                } else {
2064d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                    return mActivity.superDispatchTouchEvent(m);
2074d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                }
2084d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            } else if (MotionEvent.ACTION_MOVE == m.getActionMasked()) {
2094d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                if ((Math.abs(m.getX() - mDown.getX()) > mSlop)
2104d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                        || Math.abs(m.getY() - mDown.getY()) > mSlop) {
2117a6696dbdd858e07319b3981a405c575460fde3bMichael Kolb                    // moved too far and no timeout yet, no focus or pie
2124d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                    cancelPie();
213f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb                    if (isSwipe(m, true)) {
214571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                        mMode = MODE_MODULE;
21564f033efe1b4c00b1e532a352f28f91a28055514Michael Kolb                        return mActivity.superDispatchTouchEvent(m);
21664f033efe1b4c00b1e532a352f28f91a28055514Michael Kolb                    } else {
21764f033efe1b4c00b1e532a352f28f91a28055514Michael Kolb                        cancelActivityTouchHandling(m);
218f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb                        if (isSwipe(m , false)) {
219f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb                            mMode = MODE_NONE;
220d202574157ef3f9e655bbadc6fe87a5638ecb690Michael Kolb                        } else if (!mZoomOnly) {
221f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb                            mMode = MODE_PIE;
222f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb                            openPie();
223f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb                            sendToPie(m);
224f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb                        }
22564f033efe1b4c00b1e532a352f28f91a28055514Michael Kolb                    }
2264d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                }
2274d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            }
2284d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb            return false;
2294d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        }
2304d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
2314d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
232571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    private boolean checkReceivers(MotionEvent m) {
233571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        if (mReceivers != null) {
234571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb            for (View receiver : mReceivers) {
235571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                if (isInside(m, receiver)) {
236571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                    return true;
237571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb                }
238571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb            }
239571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        }
240571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        return false;
241571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    }
242571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb
243f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb    // left tests for finger moving right to left
244f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb    private boolean isSwipe(MotionEvent m, boolean left) {
2451cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        float dx = 0;
246f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb        float dy = 0;
2471cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        switch (mOrientation) {
2481cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        case 0:
2491cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb            dx = m.getX() - mDown.getX();
250f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            dy = Math.abs(m.getY() - mDown.getY());
251f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            break;
2521cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        case 90:
2531cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb            dx = - (m.getY() - mDown.getY());
254f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            dy = Math.abs(m.getX() - mDown.getX());
255f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            break;
2561cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        case 180:
2571cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb            dx = -(m.getX() - mDown.getX());
258f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            dy = Math.abs(m.getY() - mDown.getY());
259f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            break;
2601cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        case 270:
2611cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb            dx = m.getY() - mDown.getY();
262f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            dy = Math.abs(m.getX() - mDown.getX());
263f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            break;
264f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb        }
265f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb        if (left) {
266f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            return (dx < 0 && dy / -dx < 0.6f);
267f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb        } else {
268f39357a1c18ed8dc767cbc4033ea99a73cfd3da1Michael Kolb            return (dx > 0 && dy / dx < 0.6f);
2691cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb        }
2701cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb    }
2711cf29b911c1d8035c6862994df3cc8d4e40f31baMichael Kolb
272571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    private boolean isInside(MotionEvent evt, View v) {
273b1ddf5700f9e3950cead691cab57c4bbf03e577dMichael Kolb        v.getLocationInWindow(mLocation);
274571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb        return (v.getVisibility() == View.VISIBLE
275b1ddf5700f9e3950cead691cab57c4bbf03e577dMichael Kolb                && evt.getX() >= mLocation[0] && evt.getX() < mLocation[0] + v.getWidth()
276b1ddf5700f9e3950cead691cab57c4bbf03e577dMichael Kolb                && evt.getY() >= mLocation[1] && evt.getY() < mLocation[1] + v.getHeight());
277571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb    }
278571a6f842d972e4ac5eccfd16ed639b6779ebf98Michael Kolb
2794d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public void cancelActivityTouchHandling(MotionEvent m) {
280e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb        mActivity.superDispatchTouchEvent(makeCancelEvent(m));
281e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb    }
282e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb
283e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb    private MotionEvent makeCancelEvent(MotionEvent m) {
2844d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        MotionEvent c = MotionEvent.obtain(m);
2854d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        c.setAction(MotionEvent.ACTION_CANCEL);
286e506ca46fc7f22e2196487ecceea94534c971171Michael Kolb        return c;
2874d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
2884d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
2894d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private void openPie() {
2904d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mDown.offsetLocation(-mOverlay.getWindowPositionX(),
2914d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                -mOverlay.getWindowPositionY());
2924d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mOverlay.directDispatchTouch(mDown, mPie);
2934d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
2944d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
2954d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private void cancelPie() {
2964d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        mHandler.removeMessages(MSG_PIE);
2974d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
2984d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
2994d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    private boolean sendToPie(MotionEvent m) {
3004d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        m.offsetLocation(-mOverlay.getWindowPositionX(),
3014d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb                -mOverlay.getWindowPositionY());
3024d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        return mOverlay.directDispatchTouch(m, mPie);
3034d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
3044d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
3054d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    @Override
3064d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public boolean onScale(ScaleGestureDetector detector) {
3074d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb        return mZoom.onScale(detector);
3084d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
3094d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
3104d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    @Override
3114d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public boolean onScaleBegin(ScaleGestureDetector detector) {
3120f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb        if (mMode != MODE_ZOOM) {
3130f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb            mMode = MODE_ZOOM;
314aeccb7a572e22ca5efdec031668c6fa6a33dff17Michael Kolb            cancelActivityTouchHandling(mCurrent);
315ba7bb98f7550adee1aa99419bda412948a413fb9Michael Kolb        }
316ba7bb98f7550adee1aa99419bda412948a413fb9Michael Kolb        if (mCurrent.getActionMasked() != MotionEvent.ACTION_MOVE) {
3170f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb            return mZoom.onScaleBegin(detector);
3180f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb        } else {
3190f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb            return true;
3200f1cc66c395becb393ccd99d92475329bc6bdef5Michael Kolb        }
3214d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
3224d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb
3234d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    @Override
3244d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    public void onScaleEnd(ScaleGestureDetector detector) {
325ba7bb98f7550adee1aa99419bda412948a413fb9Michael Kolb        if (mCurrent.getActionMasked() != MotionEvent.ACTION_MOVE) {
326ba7bb98f7550adee1aa99419bda412948a413fb9Michael Kolb            mZoom.onScaleEnd(detector);
327ba7bb98f7550adee1aa99419bda412948a413fb9Michael Kolb        }
3284d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb    }
329b30f0c4cb5aa6eec6dccc879bfc9d6a4c3fd0eccMangesh Ghiware}
330