DragDownHelper.java revision ecbab3662d4474bbb45477939aaa167eb883212b
1ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi/* 2ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Copyright (C) 2014 The Android Open Source Project 3ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 4ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License"); 5ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * you may not use this file except in compliance with the License. 6ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * You may obtain a copy of the License at 7ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 8ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * http://www.apache.org/licenses/LICENSE-2.0 9ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * 10ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * Unless required by applicable law or agreed to in writing, software 11ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS, 12ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * See the License for the specific language governing permissions and 14ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * limitations under the License 15ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi */ 16ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 17ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggipackage com.android.systemui.statusbar; 18ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 19ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.content.Context; 20ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.util.ArraySet; 21ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.view.MotionEvent; 22ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.view.View; 23ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport android.view.ViewConfiguration; 24ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 25ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport com.android.systemui.ExpandHelper; 26ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport com.android.systemui.Gefingerpoken; 27ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport com.android.systemui.R; 28ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 29ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggiimport java.util.HashSet; 30ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 31ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi/** 32ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * A utility class to enable the downward swipe on the lockscreen to go to the full shade and expand 33ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi * the notification where the drag started. 34ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi */ 35ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggipublic class DragDownHelper implements Gefingerpoken { 36ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 37ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private int mMinDragDistance; 38ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private ExpandHelper.Callback mCallback; 39ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private float mInitialTouchX; 40ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private float mInitialTouchY; 41ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private boolean mDraggingDown; 42ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private float mTouchSlop; 43ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private OnDragDownListener mOnDragDownListener; 44ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private View mHost; 45ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private final int[] mTemp2 = new int[2]; 46ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private final ArraySet<View> mHoveredChildren = new ArraySet<View>(); 47ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private boolean mDraggedFarEnough; 48ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private View mStartingChild; 49ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 50ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi public DragDownHelper(Context context, View host, ExpandHelper.Callback callback, 51ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi OnDragDownListener onDragDownListener) { 52ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mMinDragDistance = context.getResources().getDimensionPixelSize( 53ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi R.dimen.keyguard_drag_down_min_distance); 54ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 55ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mCallback = callback; 56ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mOnDragDownListener = onDragDownListener; 57ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mHost = host; 58ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 59ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 60ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi @Override 61ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi public boolean onInterceptTouchEvent(MotionEvent event) { 62ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float x = event.getX(); 63ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float y = event.getY(); 64ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 65ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi switch (event.getActionMasked()) { 66ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_DOWN: 67ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mHoveredChildren.clear(); 68ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggedFarEnough = false; 69ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggingDown = false; 70ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mStartingChild = null; 71ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchY = y; 72ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchX = x; 73ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi break; 74ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 75ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_MOVE: 76ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float h = y - mInitialTouchY; 77ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) { 78ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggingDown = true; 79ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchY = y; 80ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mInitialTouchX = x; 81ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return true; 82ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 83ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi break; 84ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 85ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 86ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 87ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 88ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi @Override 89ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi public boolean onTouchEvent(MotionEvent event) { 90ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (!mDraggingDown) { 91ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 92ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 93ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float x = event.getX(); 94ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float y = event.getY(); 95ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 96ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi switch (event.getActionMasked()) { 97ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_MOVE: 98ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi final float h = y - mInitialTouchY; 99ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi View child = findView(x, y); 100ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (child != null) { 101ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi hoverChild(findView(x, y)); 102ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 103ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (h > mMinDragDistance) { 104ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (!mDraggedFarEnough) { 105ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggedFarEnough = true; 106ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mOnDragDownListener.onThresholdReached(); 107ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 108ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } else { 109ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (mDraggedFarEnough) { 110ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggedFarEnough = false; 111ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mOnDragDownListener.onReset(); 112ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 113ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 114ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return true; 115ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_UP: 116ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (mDraggedFarEnough) { 117ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mOnDragDownListener.onDraggedDown(mStartingChild); 118ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } else { 119ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi stopDragging(); 120ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 121ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 122ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi break; 123ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi case MotionEvent.ACTION_CANCEL: 124ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi stopDragging(); 125ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 126ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 127ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return false; 128ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 129ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 130ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private void stopDragging() { 131ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mDraggingDown = false; 132ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mOnDragDownListener.onReset(); 133ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 134ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 135ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private void hoverChild(View child) { 136ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (mHoveredChildren.isEmpty()) { 137ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mStartingChild = child; 138ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 139ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi if (!mHoveredChildren.contains(child)) { 140ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mOnDragDownListener.onHover(child); 141ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mHoveredChildren.add(child); 142ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 143ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 144ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 145ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi private View findView(float x, float y) { 146ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi mHost.getLocationOnScreen(mTemp2); 147ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi x += mTemp2[0]; 148ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi y += mTemp2[1]; 149ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi return mCallback.getChildAtRawPosition(x, y); 150ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 151ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi 152ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi public interface OnDragDownListener { 153ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi void onHover(View child); 154ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi void onDraggedDown(View startingChild); 155ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi void onReset(); 156ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi void onThresholdReached(); 157ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi } 158ecbab3662d4474bbb45477939aaa167eb883212bJorim Jaggi} 159