1e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller/* 2e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * Copyright (C) 2010 The Android Open Source Project 3e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * 4e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 5e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * you may not use this file except in compliance with the License. 6e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * You may obtain a copy of the License at 7e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * 8e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * http://www.apache.org/licenses/LICENSE-2.0 9e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * 10e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * Unless required by applicable law or agreed to in writing, software 11e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * distributed under the License is distributed on an "AS IS" BASIS, 12e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * See the License for the specific language governing permissions and 14e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller * limitations under the License. 15e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller */ 16e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 17e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Millerpackage com.android.systemui.statusbar; 18e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 19960892c0afa7f2b91236928e29e3987ed35b2077Jim Millerimport android.graphics.RectF; 20e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Millerimport android.view.MotionEvent; 21e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Millerimport android.view.View; 22e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 23354619c1cc1b4668c81c5368b2256335cc9e8538Jim Millerimport com.android.systemui.R; 24354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller 25e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Millerpublic class DelegateViewHelper { 26e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller private View mDelegateView; 27e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller private View mSourceView; 28e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller private BaseStatusBar mBar; 29e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller private int[] mTempPoint = new int[2]; 30354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller private float[] mDownPoint = new float[2]; 31354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller private float mTriggerThreshhold; 32960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller private boolean mPanelShowing; 33960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 34960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller RectF mInitialTouch = new RectF(); 35960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller private boolean mStarted; 36960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller private boolean mSwapXY = false; 37e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 38e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller public DelegateViewHelper(View sourceView) { 39161538985ee51e109f64af9a332d396bbffd7e2cJim Miller setSourceView(sourceView); 40e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller } 41e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 42e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller public void setDelegateView(View view) { 43e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller mDelegateView = view; 44e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller } 45e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 46e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller public void setBar(BaseStatusBar phoneStatusBar) { 47e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller mBar = phoneStatusBar; 48e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller } 49e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 50e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller public boolean onInterceptTouchEvent(MotionEvent event) { 5167ad368d4d549b431d826936e40a679099fefec8John Spurlock if (mSourceView == null || mDelegateView == null 52d5483c3157a28e2ebc05a0c918df8a2be0a7fc89Daniel Sandler || mBar.shouldDisableNavbarGestures()) { 53670d9dd2d04c2146d00b697f7f0faea258297a81Jim Miller return false; 54670d9dd2d04c2146d00b697f7f0faea258297a81Jim Miller } 55960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 56960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mSourceView.getLocationOnScreen(mTempPoint); 57960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller final float sourceX = mTempPoint[0]; 58960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller final float sourceY = mTempPoint[1]; 59960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 60960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 61e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller switch (event.getAction()) { 62e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller case MotionEvent.ACTION_DOWN: 63960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mPanelShowing = mDelegateView.getVisibility() == View.VISIBLE; 64354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller mDownPoint[0] = event.getX(); 65354619c1cc1b4668c81c5368b2256335cc9e8538Jim Miller mDownPoint[1] = event.getY(); 66960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mStarted = mInitialTouch.contains(mDownPoint[0] + sourceX, mDownPoint[1] + sourceY); 67e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller break; 68e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller } 69960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 70960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller if (!mStarted) { 71960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller return false; 72960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller } 73960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 74960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller if (!mPanelShowing && event.getAction() == MotionEvent.ACTION_MOVE) { 75960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller final int historySize = event.getHistorySize(); 76960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller for (int k = 0; k < historySize + 1; k++) { 77960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller float x = k < historySize ? event.getHistoricalX(k) : event.getX(); 78960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller float y = k < historySize ? event.getHistoricalY(k) : event.getY(); 79960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller final float distance = mSwapXY ? (mDownPoint[0] - x) : (mDownPoint[1] - y); 80960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller if (distance > mTriggerThreshhold) { 81960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mBar.showSearchPanel(); 82960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mPanelShowing = true; 83960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller break; 84e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller } 85e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller } 86960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller } 87e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 88960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mDelegateView.getLocationOnScreen(mTempPoint); 89960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller final float delegateX = mTempPoint[0]; 90960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller final float delegateY = mTempPoint[1]; 91e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller 92960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller float deltaX = sourceX - delegateX; 93960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller float deltaY = sourceY - delegateY; 94960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller event.offsetLocation(deltaX, deltaY); 95960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mDelegateView.dispatchTouchEvent(event); 96960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller event.offsetLocation(-deltaX, -deltaY); 97960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller return mPanelShowing; 98e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller } 99161538985ee51e109f64af9a332d396bbffd7e2cJim Miller 100161538985ee51e109f64af9a332d396bbffd7e2cJim Miller public void setSourceView(View view) { 101161538985ee51e109f64af9a332d396bbffd7e2cJim Miller mSourceView = view; 102161538985ee51e109f64af9a332d396bbffd7e2cJim Miller if (mSourceView != null) { 103161538985ee51e109f64af9a332d396bbffd7e2cJim Miller mTriggerThreshhold = mSourceView.getContext().getResources() 104161538985ee51e109f64af9a332d396bbffd7e2cJim Miller .getDimension(R.dimen.navbar_search_up_threshhold); 105161538985ee51e109f64af9a332d396bbffd7e2cJim Miller } 106161538985ee51e109f64af9a332d396bbffd7e2cJim Miller } 107960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 108960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller /** 109960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller * Selects the initial touch region based on a list of views. This is meant to be called by 110960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller * a container widget on children over which the initial touch should be detected. Note this 111960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller * will compute a minimum bound that contains all specified views. 112960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller * 113960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller * @param views 114960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller */ 115960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller public void setInitialTouchRegion(View ... views) { 116960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller RectF bounds = new RectF(); 117960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller int p[] = new int[2]; 118960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller for (int i = 0; i < views.length; i++) { 119960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller View view = views[i]; 120960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller if (view == null) continue; 121960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller view.getLocationOnScreen(p); 122960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller if (i == 0) { 123960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller bounds.set(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight()); 124960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller } else { 125960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller bounds.union(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight()); 126960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller } 127960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller } 128960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mInitialTouch.set(bounds); 129960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller } 130960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller 131960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller /** 132960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller * When rotation is set to NO_SENSOR, then this allows swapping x/y for gesture detection 133960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller * @param swap 134960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller */ 135960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller public void setSwapXY(boolean swap) { 136960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller mSwapXY = swap; 137960892c0afa7f2b91236928e29e3987ed35b2077Jim Miller } 138e898ac59db04d8ab0762180ca8ec7cea1347aa09Jim Miller}