blob: 9648b11ab4e7af3b81c3ecb5d41e3a685cdb0c36 [file] [log] [blame]
Jim Millere898ac52012-04-06 17:10:57 -07001/*
2 * Copyright (C) 2010 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
17package com.android.systemui.statusbar;
18
Jim Miller960892c2012-05-23 15:50:04 -070019import android.graphics.RectF;
Jim Millere898ac52012-04-06 17:10:57 -070020import android.view.MotionEvent;
Jim Millere898ac52012-04-06 17:10:57 -070021import android.view.View;
22
Jim Miller354619c2012-04-27 17:33:44 -070023import com.android.systemui.R;
24
Jim Millere898ac52012-04-06 17:10:57 -070025public class DelegateViewHelper {
Jim Millere898ac52012-04-06 17:10:57 -070026 private View mDelegateView;
27 private View mSourceView;
28 private BaseStatusBar mBar;
29 private int[] mTempPoint = new int[2];
Jim Miller354619c2012-04-27 17:33:44 -070030 private float[] mDownPoint = new float[2];
Jim Miller354619c2012-04-27 17:33:44 -070031 private float mTriggerThreshhold;
Jim Miller960892c2012-05-23 15:50:04 -070032 private boolean mPanelShowing;
33
34 RectF mInitialTouch = new RectF();
35 private boolean mStarted;
36 private boolean mSwapXY = false;
Jim Millere898ac52012-04-06 17:10:57 -070037
38 public DelegateViewHelper(View sourceView) {
Jim Miller16153892012-05-17 19:47:55 -070039 setSourceView(sourceView);
Jim Millere898ac52012-04-06 17:10:57 -070040 }
41
42 public void setDelegateView(View view) {
43 mDelegateView = view;
44 }
45
46 public void setBar(BaseStatusBar phoneStatusBar) {
47 mBar = phoneStatusBar;
48 }
49
Jim Millere898ac52012-04-06 17:10:57 -070050 public boolean onInterceptTouchEvent(MotionEvent event) {
John Spurlock67ad3682012-06-26 17:42:00 -040051 if (mSourceView == null || mDelegateView == null
Daniel Sandlerd5483c32012-10-19 16:44:15 -040052 || mBar.shouldDisableNavbarGestures()) {
Jim Miller670d9dd2012-05-12 13:28:26 -070053 return false;
54 }
Jim Miller960892c2012-05-23 15:50:04 -070055
56 mSourceView.getLocationOnScreen(mTempPoint);
57 final float sourceX = mTempPoint[0];
58 final float sourceY = mTempPoint[1];
59
John Spurlockad3e6cb2013-04-30 08:47:43 -040060 final int action = event.getAction();
61 switch (action) {
Jim Millere898ac52012-04-06 17:10:57 -070062 case MotionEvent.ACTION_DOWN:
Jim Miller960892c2012-05-23 15:50:04 -070063 mPanelShowing = mDelegateView.getVisibility() == View.VISIBLE;
Jim Miller354619c2012-04-27 17:33:44 -070064 mDownPoint[0] = event.getX();
65 mDownPoint[1] = event.getY();
Jim Miller960892c2012-05-23 15:50:04 -070066 mStarted = mInitialTouch.contains(mDownPoint[0] + sourceX, mDownPoint[1] + sourceY);
Jim Millere898ac52012-04-06 17:10:57 -070067 break;
68 }
Jim Miller960892c2012-05-23 15:50:04 -070069
70 if (!mStarted) {
71 return false;
72 }
73
John Spurlockad3e6cb2013-04-30 08:47:43 -040074 if (!mPanelShowing && action == MotionEvent.ACTION_MOVE) {
Jim Miller960892c2012-05-23 15:50:04 -070075 final int historySize = event.getHistorySize();
76 for (int k = 0; k < historySize + 1; k++) {
77 float x = k < historySize ? event.getHistoricalX(k) : event.getX();
78 float y = k < historySize ? event.getHistoricalY(k) : event.getY();
79 final float distance = mSwapXY ? (mDownPoint[0] - x) : (mDownPoint[1] - y);
80 if (distance > mTriggerThreshhold) {
81 mBar.showSearchPanel();
82 mPanelShowing = true;
83 break;
Jim Millere898ac52012-04-06 17:10:57 -070084 }
85 }
Jim Millere898ac52012-04-06 17:10:57 -070086 }
Jim Miller960892c2012-05-23 15:50:04 -070087
John Spurlockad3e6cb2013-04-30 08:47:43 -040088 if (action == MotionEvent.ACTION_DOWN) {
89 mBar.suspendAutohide();
90 } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
91 mBar.resumeAutohide();
92 }
93
Jim Miller960892c2012-05-23 15:50:04 -070094 mDelegateView.getLocationOnScreen(mTempPoint);
95 final float delegateX = mTempPoint[0];
96 final float delegateY = mTempPoint[1];
97
98 float deltaX = sourceX - delegateX;
99 float deltaY = sourceY - delegateY;
100 event.offsetLocation(deltaX, deltaY);
101 mDelegateView.dispatchTouchEvent(event);
102 event.offsetLocation(-deltaX, -deltaY);
103 return mPanelShowing;
Jim Millere898ac52012-04-06 17:10:57 -0700104 }
Jim Miller16153892012-05-17 19:47:55 -0700105
106 public void setSourceView(View view) {
107 mSourceView = view;
108 if (mSourceView != null) {
109 mTriggerThreshhold = mSourceView.getContext().getResources()
110 .getDimension(R.dimen.navbar_search_up_threshhold);
111 }
112 }
Jim Miller960892c2012-05-23 15:50:04 -0700113
114 /**
115 * Selects the initial touch region based on a list of views. This is meant to be called by
116 * a container widget on children over which the initial touch should be detected. Note this
117 * will compute a minimum bound that contains all specified views.
118 *
119 * @param views
120 */
121 public void setInitialTouchRegion(View ... views) {
122 RectF bounds = new RectF();
123 int p[] = new int[2];
124 for (int i = 0; i < views.length; i++) {
125 View view = views[i];
126 if (view == null) continue;
127 view.getLocationOnScreen(p);
128 if (i == 0) {
129 bounds.set(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
130 } else {
131 bounds.union(p[0], p[1], p[0] + view.getWidth(), p[1] + view.getHeight());
132 }
133 }
134 mInitialTouch.set(bounds);
135 }
136
137 /**
138 * When rotation is set to NO_SENSOR, then this allows swapping x/y for gesture detection
139 * @param swap
140 */
141 public void setSwapXY(boolean swap) {
142 mSwapXY = swap;
143 }
Jim Millere898ac52012-04-06 17:10:57 -0700144}