DragLayer.java revision 50e5165b78c75ccb022f0954699f49c579547115
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevpackage com.android.launcher3.dragndrop; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.Animator; 20716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.AnimatorListenerAdapter; 21716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.TimeInterpolator; 22716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator; 23716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener; 2431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 25716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.content.res.Resources; 26360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chungimport android.graphics.Canvas; 270fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyalimport android.graphics.Color; 286788269814a678af976dfc7d6135993e172ce586Adam Cohenimport android.graphics.Rect; 2995cdb3a0211650e76adb451588ce89fd585b178fTony Wickhamimport android.graphics.Region; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 3126279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.KeyEvent; 3208ca40f97670ad56ea01a81a439e89a484f9fdb5Sunny Goyalimport android.view.LayoutInflater; 3326279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.MotionEvent; 3426279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.View; 3526279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.ViewGroup; 363371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityEvent; 373371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityManager; 38716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.view.animation.DecelerateInterpolator; 393e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.view.animation.Interpolator; 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.FrameLayout; 41ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohenimport android.widget.TextView; 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 43740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyalimport com.android.launcher3.AbstractFloatingView; 44fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.AppWidgetResizeFrame; 45fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.CellLayout; 461bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickhamimport com.android.launcher3.DropTargetBar; 47740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyalimport com.android.launcher3.ExtendedEditText; 48fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.InsettableFrameLayout; 49fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Launcher; 50fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.LauncherAppWidgetHostView; 51dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickhamimport com.android.launcher3.PinchToOverviewListener; 52f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohenimport com.android.launcher3.R; 53fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.ShortcutAndWidgetContainer; 54fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Utilities; 55645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.allapps.AllAppsTransitionController; 569c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickhamimport com.android.launcher3.config.FeatureFlags; 57261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.folder.Folder; 58261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.folder.FolderIcon; 593333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyalimport com.android.launcher3.keyboard.ViewGroupFocusHelper; 60c6cf493b07fc7234c2a0a164318fd9aeb02e48f3Jon Mirandaimport com.android.launcher3.logging.LoggerUtils; 61c6cf493b07fc7234c2a0a164318fd9aeb02e48f3Jon Mirandaimport com.android.launcher3.userevent.nano.LauncherLogProto; 62091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 63645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Songimport com.android.launcher3.util.TouchController; 6450e5165b78c75ccb022f0954699f49c579547115Tony Wickhamimport com.android.launcher3.widget.WidgetsAndMore; 65bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 661d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohenimport java.util.ArrayList; 676788269814a678af976dfc7d6135993e172ce586Adam Cohen 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 690e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * A ViewGroup that coordinates dragging across its descendants 7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 71a6d0492e5f0dd4e1b43d4034a770241dc65f8f8cAdam Cohenpublic class DragLayer extends InsettableFrameLayout { 720fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal 73b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal public static final int ANIMATION_END_DISAPPEAR = 0; 74b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal public static final int ANIMATION_END_REMAIN_VISIBLE = 2; 75b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal 760fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal // Scrim color without any alpha component. 770fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal private static final int SCRIM_COLOR = Color.BLACK & 0x00FFFFFF; 780fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal 79b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal private final int[] mTmpXY = new int[2]; 80b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal 81091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk DragController mDragController; 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 83716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private Launcher mLauncher; 84716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 856788269814a678af976dfc7d6135993e172ce586Adam Cohen // Variables relating to resizing widgets 867066003b2032a49ae5e59dab9b706259bdeb7e6eSunny Goyal private final boolean mIsRtl; 876788269814a678af976dfc7d6135993e172ce586Adam Cohen private AppWidgetResizeFrame mCurrentResizeFrame; 88716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 89716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Variables relating to animation of views after drop 90716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private ValueAnimator mDropAnim = null; 91b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal private final TimeInterpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f); 92091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk DragView mDropView = null; 93091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mAnchorViewInitialScrollX = 0; 94091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk View mAnchorView = null; 958dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 963371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean mHoverPointClosesFolder = false; 97b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal private final Rect mHitRect = new Rect(); 9895cdb3a0211650e76adb451588ce89fd585b178fTony Wickham private final Rect mHighlightRect = new Rect(); 996788269814a678af976dfc7d6135993e172ce586Adam Cohen 100b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen private TouchCompleteListener mTouchCompleteListener; 101b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen 102432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen private int mTopViewIndex; 1032d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen private int mChildCountOnLastUpdate = -1; 10455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 1056c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen // Darkening scrim 1066c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen private float mBackgroundAlpha = 0; 1076c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 1080f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham // Related to adjacent page hints 1090f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private final Rect mScrollChildPosition = new Rect(); 1103333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal private final ViewGroupFocusHelper mFocusIndicatorHelper; 1113333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal 112dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham // Related to pinch-to-go-to-overview gesture. 1139c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickham private PinchToOverviewListener mPinchListener = null; 114645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 115645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song // Handles all apps pull up interaction 116645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song private AllAppsTransitionController mAllAppsController; 117645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 118645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song private TouchController mActiveController; 11931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to create a new DragLayer from XML. 12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1230e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public DragLayer(Context context, AttributeSet attrs) { 12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 127be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung 128be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung // Disable multitouch across the workspace/all apps/customize tray 129be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung setMotionEventSplittingEnabled(false); 13021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen setChildrenDrawingOrderEnabled(true); 131360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung 132f5440cbd6c0525769d24b890e16313a728831e04Sunny Goyal mIsRtl = Utilities.isRtl(getResources()); 1333333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal mFocusIndicatorHelper = new ViewGroupFocusHelper(this); 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 136645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song public void setup(Launcher launcher, DragController dragController, 137645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song AllAppsTransitionController allAppsTransitionController) { 1384c98d9235d164680186180974719f551cf935d08Winson Chung mLauncher = launcher; 139645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mDragController = dragController; 140645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mAllAppsController = allAppsTransitionController; 141dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham 142e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham boolean isAccessibilityEnabled = ((AccessibilityManager) mLauncher.getSystemService( 143e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham Context.ACCESSIBILITY_SERVICE)).isEnabled(); 144e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham onAccessibilityStateChanged(isAccessibilityEnabled); 14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 1473333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal public ViewGroupFocusHelper getFocusIndicatorHelper() { 1483333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal return mFocusIndicatorHelper; 1493333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal } 1503333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal 15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 15300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); 15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 156e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham public void onAccessibilityStateChanged(boolean isAccessibilityEnabled) { 157e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham mPinchListener = FeatureFlags.LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW || isAccessibilityEnabled 158e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham ? null : new PinchToOverviewListener(mLauncher); 159e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham } 160e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham 1617744169812e0d35531e9de258785af1f2ec9bed3Hyunyoung Song public boolean isEventOverPageIndicator(MotionEvent ev) { 162740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal return isEventOverView(mLauncher.getWorkspace().getPageIndicator(), ev); 1637744169812e0d35531e9de258785af1f2ec9bed3Hyunyoung Song } 1647744169812e0d35531e9de258785af1f2ec9bed3Hyunyoung Song 165a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song public boolean isEventOverHotseat(MotionEvent ev) { 1661bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham return isEventOverView(mLauncher.getHotseat(), ev); 167a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song } 168a9a8a4221709cc3fda48fd80d4213d25183b8bf7Hyunyoung Song 1693371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean isEventOverFolder(Folder folder, MotionEvent ev) { 1701bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham return isEventOverView(folder, ev); 1713371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1723371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 173ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal private boolean isEventOverDropTargetBar(MotionEvent ev) { 1741bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham return isEventOverView(mLauncher.getDropTargetBar(), ev); 1751bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham } 1761bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham 17758a9c4b7d2aa3772f56fea32f82cf29d410dc499Hyunyoung Song public boolean isEventOverView(View view, MotionEvent ev) { 1781bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham getDescendantRectRelativeToSelf(view, mHitRect); 17947328fd53f43fd0c2ed14ad925dd04483f9229a0Sunny Goyal return mHitRect.contains((int) ev.getX(), (int) ev.getY()); 180ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 181ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 18276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean handleTouchDown(MotionEvent ev, boolean intercept) { 183740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher); 184740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal if (topView != null && intercept) { 185740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal ExtendedEditText textView = topView.getActiveTextView(); 186740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal if (textView != null) { 187740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal if (!isEventOverView(textView, ev)) { 188740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal textView.dispatchBackKey(); 189740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal return true; 190740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal } 191740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal } else if (!isEventOverView(topView, ev)) { 1922f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham if (isInAccessibleDrag()) { 1932f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham // Do not close the container if in drag and drop. 1942f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham if (!isEventOverDropTargetBar(ev)) { 1952f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham return true; 1962f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham } 1972f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham } else { 198c6cf493b07fc7234c2a0a164318fd9aeb02e48f3Jon Miranda mLauncher.getUserEventDispatcher().logActionTapOutside( 199c6cf493b07fc7234c2a0a164318fd9aeb02e48f3Jon Miranda LoggerUtils.newContainerTarget(topView.getLogContainerType())); 200740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal topView.close(true); 201740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal 2022f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham // We let touches on the original icon go through so that users can launch 2032f2104ccdfd0f47d20e959982c52d36dfc7760ffTony Wickham // the app with one tap if they don't find a shortcut they want. 204740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal View extendedTouch = topView.getExtendedTouchView(); 205740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal return extendedTouch == null || !isEventOverView(extendedTouch, ev); 206ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 20776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 2082801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 2096788269814a678af976dfc7d6135993e172ce586Adam Cohen return false; 2106788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2116788269814a678af976dfc7d6135993e172ce586Adam Cohen 21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent ev) { 214b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen int action = ev.getAction(); 215b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen 216b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (action == MotionEvent.ACTION_DOWN) { 217c001cf562017d08cd48b67de8f377ca08881e70eHyunyoung Song // Cancel discovery bounce animation when a user start interacting on anywhere on 218c001cf562017d08cd48b67de8f377ca08881e70eHyunyoung Song // dray layer even if mAllAppsController is NOT the active controller. 219c001cf562017d08cd48b67de8f377ca08881e70eHyunyoung Song // TODO: handle other input other than touch 220c001cf562017d08cd48b67de8f377ca08881e70eHyunyoung Song mAllAppsController.cancelDiscoveryAnimation(); 22176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, true)) { 2226788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 223d1837cc69eb222371afdd30890f7215d117510f2Patrick Dubroy } 224b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 225b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (mTouchCompleteListener != null) { 226b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener.onTouchComplete(); 227b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 228b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener = null; 2291b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen } 23098cbd62e1f6d57ccef1758fb82dd245f7354fb73Tony Wickham mActiveController = null; 23198cbd62e1f6d57ccef1758fb82dd245f7354fb73Tony Wickham 2326ad72f02fd233f2294222477102e83d721100493Sunny Goyal if (mCurrentResizeFrame != null 2336ad72f02fd233f2294222477102e83d721100493Sunny Goyal && mCurrentResizeFrame.onControllerInterceptTouchEvent(ev)) { 2346ad72f02fd233f2294222477102e83d721100493Sunny Goyal mActiveController = mCurrentResizeFrame; 2356ad72f02fd233f2294222477102e83d721100493Sunny Goyal return true; 2366ad72f02fd233f2294222477102e83d721100493Sunny Goyal } else { 2376ad72f02fd233f2294222477102e83d721100493Sunny Goyal clearResizeFrame(); 2386ad72f02fd233f2294222477102e83d721100493Sunny Goyal } 2396ad72f02fd233f2294222477102e83d721100493Sunny Goyal 2406ad72f02fd233f2294222477102e83d721100493Sunny Goyal if (mDragController.onControllerInterceptTouchEvent(ev)) { 241645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mActiveController = mDragController; 242645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return true; 243645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 2441bce7fd342875be8f7c1f82c8cf21d0199c8d544Tony Wickham 2456ad72f02fd233f2294222477102e83d721100493Sunny Goyal if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && mAllAppsController.onControllerInterceptTouchEvent(ev)) { 246645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mActiveController = mAllAppsController; 247645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return true; 24850e5165b78c75ccb022f0954699f49c579547115Tony Wickham } 24950e5165b78c75ccb022f0954699f49c579547115Tony Wickham 25050e5165b78c75ccb022f0954699f49c579547115Tony Wickham WidgetsAndMore widgetsAndMore = WidgetsAndMore.getOpen(mLauncher); 25150e5165b78c75ccb022f0954699f49c579547115Tony Wickham if (widgetsAndMore != null && widgetsAndMore.onControllerInterceptTouchEvent(ev)) { 25250e5165b78c75ccb022f0954699f49c579547115Tony Wickham mActiveController = widgetsAndMore; 25350e5165b78c75ccb022f0954699f49c579547115Tony Wickham return true; 254645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 255645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song 2566ad72f02fd233f2294222477102e83d721100493Sunny Goyal if (mPinchListener != null && mPinchListener.onControllerInterceptTouchEvent(ev)) { 257c5b31965d9bcb4c9899e2d1c45b5c95c70bac9f2Tony Wickham // Stop listening for scrolling etc. (onTouchEvent() handles the rest of the pinch.) 258645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song mActiveController = mPinchListener; 259c5b31965d9bcb4c9899e2d1c45b5c95c70bac9f2Tony Wickham return true; 260dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham } 261645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return false; 26231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 2653371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onInterceptHoverEvent(MotionEvent ev) { 266023c71eb3b2bbe63272cb74baaf050c4188c89b0Michael Jurka if (mLauncher == null || mLauncher.getWorkspace() == null) { 267023c71eb3b2bbe63272cb74baaf050c4188c89b0Michael Jurka return false; 268023c71eb3b2bbe63272cb74baaf050c4188c89b0Michael Jurka } 269740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal Folder currentFolder = Folder.getOpen(mLauncher); 2703371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (currentFolder == null) { 2713371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 2723371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 2738b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 2748b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 2758b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isTouchExplorationEnabled()) { 2763371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen final int action = ev.getAction(); 277ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal boolean isOverFolderOrSearchBar; 2783371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen switch (action) { 2793371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_ENTER: 280ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) || 281ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal (isInAccessibleDrag() && isEventOverDropTargetBar(ev)); 282ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (!isOverFolderOrSearchBar) { 2833371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 2843371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 2853371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 2863371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 287693fbc7f1737d89f11f9ab81558c109f0883ab0eMihail Dumitrescu mHoverPointClosesFolder = false; 288693fbc7f1737d89f11f9ab81558c109f0883ab0eMihail Dumitrescu break; 2893371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_MOVE: 290ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) || 291ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal (isInAccessibleDrag() && isEventOverDropTargetBar(ev)); 292ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (!isOverFolderOrSearchBar && !mHoverPointClosesFolder) { 2933371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 2943371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 2953371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 296ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } else if (!isOverFolderOrSearchBar) { 2973371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 2983371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 299693fbc7f1737d89f11f9ab81558c109f0883ab0eMihail Dumitrescu mHoverPointClosesFolder = false; 3003371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3013371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3023371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3033371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 3043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3053371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 3063371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private void sendTapOutsideFolderAccessibilityEvent(boolean isEditingName) { 30752851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal int stringId = isEditingName ? R.string.folder_tap_to_rename : R.string.folder_tap_to_close; 30852851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal Utilities.sendCustomAccessibilityEvent( 30952851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal this, AccessibilityEvent.TYPE_VIEW_FOCUSED, getContext().getString(stringId)); 31083ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 31183ca480941b3dd635b62347008fc8d7859d82002Winson Chung 312ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal private boolean isInAccessibleDrag() { 313ae50284e0a838139c67caf0064a0977c871497faSunny Goyal return mLauncher.getAccessibilityDelegate().isInAccessibleDrag(); 314ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 315ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 31683ca480941b3dd635b62347008fc8d7859d82002Winson Chung @Override 31783ca480941b3dd635b62347008fc8d7859d82002Winson Chung public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { 3187d552c8b18cfad9f32fb5028c53960a9f19dc0a8Sunny Goyal // Shortcuts can appear above folder 319740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal View topView = AbstractFloatingView.getTopOpenView(mLauncher); 3207d552c8b18cfad9f32fb5028c53960a9f19dc0a8Sunny Goyal if (topView != null) { 32152851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal if (child == topView) { 32252851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal return super.onRequestSendAccessibilityEvent(child, event); 32352851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } 32452851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal if (isInAccessibleDrag() && child instanceof DropTargetBar) { 32552851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal return super.onRequestSendAccessibilityEvent(child, event); 32652851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } 32752851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal // Skip propagating onRequestSendAccessibilityEvent for all other children 32852851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal // which are not topView 32952851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal return false; 33083ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 33183ca480941b3dd635b62347008fc8d7859d82002Winson Chung return super.onRequestSendAccessibilityEvent(child, event); 33283ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 33383ca480941b3dd635b62347008fc8d7859d82002Winson Chung 33483ca480941b3dd635b62347008fc8d7859d82002Winson Chung @Override 33583ca480941b3dd635b62347008fc8d7859d82002Winson Chung public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) { 336740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal View topView = AbstractFloatingView.getTopOpenView(mLauncher); 33752851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal if (topView != null) { 33852851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal // Only add the top view as a child for accessibility when it is open 33952851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal childrenForAccessibility.add(topView); 340ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 341ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (isInAccessibleDrag()) { 34247328fd53f43fd0c2ed14ad925dd04483f9229a0Sunny Goyal childrenForAccessibility.add(mLauncher.getDropTargetBar()); 343ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 34483ca480941b3dd635b62347008fc8d7859d82002Winson Chung } else { 34583ca480941b3dd635b62347008fc8d7859d82002Winson Chung super.addChildrenForAccessibility(childrenForAccessibility); 34683ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 3473371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3483371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 3493371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 3503371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onHoverEvent(MotionEvent ev) { 3513371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // If we've received this, we've already done the necessary handling 3523371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // in onInterceptHoverEvent. Return true to consume the event. 3533371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 3543371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3553371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 3563371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 3586788269814a678af976dfc7d6135993e172ce586Adam Cohen int action = ev.getAction(); 3596788269814a678af976dfc7d6135993e172ce586Adam Cohen 360b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (action == MotionEvent.ACTION_DOWN) { 361b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (handleTouchDown(ev, false)) { 362b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen return true; 363b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 364b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 365b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (mTouchCompleteListener != null) { 366b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener.onTouchComplete(); 3676788269814a678af976dfc7d6135993e172ce586Adam Cohen } 368b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener = null; 3696788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3706788269814a678af976dfc7d6135993e172ce586Adam Cohen 371645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song if (mActiveController != null) { 3726ad72f02fd233f2294222477102e83d721100493Sunny Goyal return mActiveController.onControllerTouchEvent(ev); 373645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song } 374645764e3e5fa34d9adcddfc722d726b76f048306Hyunyoung Song return false; 37591a9c9636f10f1e12cd1f660b2e330634fbdc7dcRomain Guy } 376ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 37735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 37835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Determine the rect of the descendant in this DragLayer's coordinates 37935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 38035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant whose coordinates we want to find. 38135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param r The rect into which to place the results. 38235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. 38335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 384ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen public float getDescendantRectRelativeToSelf(View descendant, Rect r) { 385716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[0] = 0; 386716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[1] = 0; 387ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen float scale = getDescendantCoordRelativeToSelf(descendant, mTmpXY); 3887d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen 3898dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen r.set(mTmpXY[0], mTmpXY[1], 3907d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen (int) (mTmpXY[0] + scale * descendant.getMeasuredWidth()), 3917d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen (int) (mTmpXY[1] + scale * descendant.getMeasuredHeight())); 392ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen return scale; 393716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 39476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 395307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen public float getLocationInDragLayer(View child, int[] loc) { 39635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[0] = 0; 39735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[1] = 0; 398307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen return getDescendantCoordRelativeToSelf(child, loc); 39935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 40035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 4017d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public float getDescendantCoordRelativeToSelf(View descendant, int[] coord) { 4027d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen return getDescendantCoordRelativeToSelf(descendant, coord, false); 4037d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen } 4047d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen 40535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 40635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Given a coordinate relative to the descendant, find the coordinate in this DragLayer's 40735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * coordinates. 40835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 40935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant to which the passed coordinate is relative. 41035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param coord The coordinate that we want mapped. 4117d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen * @param includeRootScroll Whether or not to account for the scroll of the root descendant: 4127d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen * sometimes this is relevant as in a child's coordinates within the root descendant. 413307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. Caution 414307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen * this scale factor is assumed to be equal in X and Y, and so if at any point this 415307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen * assumption fails, we will need to return a pair of scale factors. 41635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 4177d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public float getDescendantCoordRelativeToSelf(View descendant, int[] coord, 4187d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen boolean includeRootScroll) { 419e8b5d20d94cb03878137a7fdf65d7a88270b73f8Sunny Goyal return Utilities.getDescendantCoordRelativeToAncestor(descendant, this, 420c9ca2980983ab21fc8631c7a65399d6d9c70f39cWinson Chung coord, includeRootScroll); 421c9ca2980983ab21fc8631c7a65399d6d9c70f39cWinson Chung } 422c9ca2980983ab21fc8631c7a65399d6d9c70f39cWinson Chung 4237d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen /** 4247d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen * Inverse of {@link #getDescendantCoordRelativeToSelf(View, int[])}. 4257d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen */ 4265e0e94f0b2ae79770dd07b66441fda6e063e64eaSunny Goyal public void mapCoordInSelfToDescendant(View descendant, int[] coord) { 4275e0e94f0b2ae79770dd07b66441fda6e063e64eaSunny Goyal Utilities.mapCoordInSelfToDescendant(descendant, this, coord); 42876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 42976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 4303e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void getViewRectRelativeToSelf(View v, Rect r) { 4313e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int[] loc = new int[2]; 4328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen getLocationInWindow(loc); 4333e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int x = loc[0]; 4343e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int y = loc[1]; 435716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4368dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen v.getLocationInWindow(loc); 4373e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vX = loc[0]; 4383e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vY = loc[1]; 439716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4403e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int left = vX - x; 4413e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int top = vY - y; 4423e8f811f31a2275e778244427271f77f4116c08bAdam Cohen r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight()); 443716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 444716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 445ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy @Override 446ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy public boolean dispatchUnhandledMove(View focused, int direction) { 4478dd5168b0582a20a4ede5ccfd21d227118fd9743Tony Wickham // Consume the unhandled move if a container is open, to avoid switching pages underneath. 448740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal boolean isContainerOpen = AbstractFloatingView.getTopOpenView(mLauncher) != null; 4498dd5168b0582a20a4ede5ccfd21d227118fd9743Tony Wickham return isContainerOpen || mDragController.dispatchUnhandledMove(focused, direction); 450ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy } 451120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen 452bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 453bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public LayoutParams generateLayoutParams(AttributeSet attrs) { 454bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return new LayoutParams(getContext(), attrs); 455bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 456bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 457bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 458bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen protected LayoutParams generateDefaultLayoutParams() { 459bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 460bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 461bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 462bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen // Override to allow type-checking of LayoutParams. 463bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 464bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 465bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return p instanceof LayoutParams; 466bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 467bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 468bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 469bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 470bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return new LayoutParams(p); 471bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 472bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 473bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public static class LayoutParams extends InsettableFrameLayout.LayoutParams { 4746788269814a678af976dfc7d6135993e172ce586Adam Cohen public int x, y; 4756788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean customPosition = false; 4766788269814a678af976dfc7d6135993e172ce586Adam Cohen 477bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public LayoutParams(Context c, AttributeSet attrs) { 478bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen super(c, attrs); 479bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 480bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 4816788269814a678af976dfc7d6135993e172ce586Adam Cohen public LayoutParams(int width, int height) { 4826788269814a678af976dfc7d6135993e172ce586Adam Cohen super(width, height); 4836788269814a678af976dfc7d6135993e172ce586Adam Cohen } 4846788269814a678af976dfc7d6135993e172ce586Adam Cohen 485bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public LayoutParams(ViewGroup.LayoutParams lp) { 486bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen super(lp); 487bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 488bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 4896788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setWidth(int width) { 4906788269814a678af976dfc7d6135993e172ce586Adam Cohen this.width = width; 4916788269814a678af976dfc7d6135993e172ce586Adam Cohen } 4926788269814a678af976dfc7d6135993e172ce586Adam Cohen 4936788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getWidth() { 4946788269814a678af976dfc7d6135993e172ce586Adam Cohen return width; 4956788269814a678af976dfc7d6135993e172ce586Adam Cohen } 4966788269814a678af976dfc7d6135993e172ce586Adam Cohen 4976788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setHeight(int height) { 4986788269814a678af976dfc7d6135993e172ce586Adam Cohen this.height = height; 4996788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5006788269814a678af976dfc7d6135993e172ce586Adam Cohen 5016788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getHeight() { 5026788269814a678af976dfc7d6135993e172ce586Adam Cohen return height; 5036788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5046788269814a678af976dfc7d6135993e172ce586Adam Cohen 5056788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setX(int x) { 5066788269814a678af976dfc7d6135993e172ce586Adam Cohen this.x = x; 5076788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5086788269814a678af976dfc7d6135993e172ce586Adam Cohen 5096788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getX() { 5106788269814a678af976dfc7d6135993e172ce586Adam Cohen return x; 5116788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5126788269814a678af976dfc7d6135993e172ce586Adam Cohen 5136788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setY(int y) { 5146788269814a678af976dfc7d6135993e172ce586Adam Cohen this.y = y; 5156788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5166788269814a678af976dfc7d6135993e172ce586Adam Cohen 5176788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getY() { 5186788269814a678af976dfc7d6135993e172ce586Adam Cohen return y; 5196788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5206788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5216788269814a678af976dfc7d6135993e172ce586Adam Cohen 5226788269814a678af976dfc7d6135993e172ce586Adam Cohen protected void onLayout(boolean changed, int l, int t, int r, int b) { 5236788269814a678af976dfc7d6135993e172ce586Adam Cohen super.onLayout(changed, l, t, r, b); 5246788269814a678af976dfc7d6135993e172ce586Adam Cohen int count = getChildCount(); 5256788269814a678af976dfc7d6135993e172ce586Adam Cohen for (int i = 0; i < count; i++) { 5266788269814a678af976dfc7d6135993e172ce586Adam Cohen View child = getChildAt(i); 5276788269814a678af976dfc7d6135993e172ce586Adam Cohen final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams(); 5286788269814a678af976dfc7d6135993e172ce586Adam Cohen if (flp instanceof LayoutParams) { 5296788269814a678af976dfc7d6135993e172ce586Adam Cohen final LayoutParams lp = (LayoutParams) flp; 5306788269814a678af976dfc7d6135993e172ce586Adam Cohen if (lp.customPosition) { 5316788269814a678af976dfc7d6135993e172ce586Adam Cohen child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height); 5326788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5336788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5346788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5356788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5366788269814a678af976dfc7d6135993e172ce586Adam Cohen 5376ad72f02fd233f2294222477102e83d721100493Sunny Goyal public void clearResizeFrame() { 5386ad72f02fd233f2294222477102e83d721100493Sunny Goyal if (mCurrentResizeFrame != null) { 5396ad72f02fd233f2294222477102e83d721100493Sunny Goyal mCurrentResizeFrame.commitResize(); 5406ad72f02fd233f2294222477102e83d721100493Sunny Goyal removeView(mCurrentResizeFrame); 5416ad72f02fd233f2294222477102e83d721100493Sunny Goyal mCurrentResizeFrame = null; 5426788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5436788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5446788269814a678af976dfc7d6135993e172ce586Adam Cohen 5456ad72f02fd233f2294222477102e83d721100493Sunny Goyal public void addResizeFrame(LauncherAppWidgetHostView widget, CellLayout cellLayout) { 5466ad72f02fd233f2294222477102e83d721100493Sunny Goyal clearResizeFrame(); 5476788269814a678af976dfc7d6135993e172ce586Adam Cohen 54808ca40f97670ad56ea01a81a439e89a484f9fdb5Sunny Goyal mCurrentResizeFrame = (AppWidgetResizeFrame) LayoutInflater.from(mLauncher) 54908ca40f97670ad56ea01a81a439e89a484f9fdb5Sunny Goyal .inflate(R.layout.app_widget_resize_frame, this, false); 55008ca40f97670ad56ea01a81a439e89a484f9fdb5Sunny Goyal mCurrentResizeFrame.setupForWidget(widget, cellLayout, this); 55108ca40f97670ad56ea01a81a439e89a484f9fdb5Sunny Goyal ((LayoutParams) mCurrentResizeFrame.getLayoutParams()).customPosition = true; 5526788269814a678af976dfc7d6135993e172ce586Adam Cohen 55308ca40f97670ad56ea01a81a439e89a484f9fdb5Sunny Goyal addView(mCurrentResizeFrame); 5546ad72f02fd233f2294222477102e83d721100493Sunny Goyal mCurrentResizeFrame.snapToWidget(false); 5556788269814a678af976dfc7d6135993e172ce586Adam Cohen } 556716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 5577bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha, 5587bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable, 5597bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int duration) { 560b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen Rect r = new Rect(); 561b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen getViewRectRelativeToSelf(dragView, r); 562b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromX = r.left; 563b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromY = r.top; 564b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen 5657bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], alpha, 1, 1, scaleX, scaleY, 566ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen onFinishRunnable, animationEndStyle, duration, null); 567ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 568ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 569557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung public void animateViewIntoPosition(DragView dragView, final View child, 57028f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen final Runnable onFinishAnimationRunnable, View anchorView) { 57128f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen animateViewIntoPosition(dragView, child, -1, onFinishAnimationRunnable, anchorView); 572ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen } 573ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen 574ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen public void animateViewIntoPosition(DragView dragView, final View child, int duration, 5756441de0ec2a71862798dd51180d0811b42edd514Adam Cohen final Runnable onFinishAnimationRunnable, View anchorView) { 576a52570f8f9ad65b85e33a2f2e87722f9edd6c6f4Michael Jurka ShortcutAndWidgetContainer parentChildren = (ShortcutAndWidgetContainer) child.getParent(); 577716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 578eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung parentChildren.measureChild(child); 579716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 5803e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect r = new Rect(); 5813e8f811f31a2275e778244427271f77f4116c08bAdam Cohen getViewRectRelativeToSelf(dragView, r); 582716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 583716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen int coord[] = new int[2]; 584307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen float childScale = child.getScaleX(); 585307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen coord[0] = lp.x + (int) (child.getMeasuredWidth() * (1 - childScale) / 2); 586307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen coord[1] = lp.y + (int) (child.getMeasuredHeight() * (1 - childScale) / 2); 587eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung 5888dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen // Since the child hasn't necessarily been laid out, we force the lp to be updated with 589ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // the correct coordinates (above) and use these to determine the final location 590557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = getDescendantCoordRelativeToSelf((View) child.getParent(), coord); 591307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen // We need to account for the scale of the child itself, as the above only accounts for 592307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen // for the scale in parents. 593307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen scale *= childScale; 594ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toX = coord[0]; 595ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toY = coord[1]; 596eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung float toScale = scale; 5974497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn if (child instanceof TextView) { 5984497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn TextView tv = (TextView) child; 599eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // Account for the source scale of the icon (ie. from AllApps to Workspace, in which 600eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // the workspace may have smaller icon bounds). 601eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung toScale = scale / dragView.getIntrinsicIconScaleFactor(); 6024497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn 6034497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn // The child may be scaled (always about the center of the view) so to account for it, 6044497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn // we have to offset the position by the scaled size. Once we do that, we can center 6054497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn // the drag view about the scaled child view. 606eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung toY += Math.round(toScale * tv.getPaddingTop()); 607eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung toY -= dragView.getMeasuredHeight() * (1 - toScale) / 2; 60895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal if (dragView.getDragVisualizeOffset() != null) { 60995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal toY -= Math.round(toScale * dragView.getDragVisualizeOffset().y); 61095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal } 61195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal 6124497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 6134497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn } else if (child instanceof FolderIcon) { 614ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Account for holographic blur padding on the drag view 6155f8afe6280eae34620067696173e71943e1a30a3Winson Chung toY += Math.round(scale * (child.getPaddingTop() - dragView.getDragRegionTop())); 616c9c57631a985a8e1a4eac17ef0952bd344e281a2Jon Miranda toY -= scale * dragView.getBlurSizeOutline() / 2; 617307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen toY -= (1 - scale) * dragView.getMeasuredHeight() / 2; 618ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Center in the x coordinate about the target's drawable 619ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 620ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } else { 621ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY -= (Math.round(scale * (dragView.getHeight() - child.getMeasuredHeight()))) / 2; 622ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (Math.round(scale * (dragView.getMeasuredWidth() 623ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen - child.getMeasuredWidth()))) / 2; 624ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } 625716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 626ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromX = r.left; 627ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromY = r.top; 628716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen child.setVisibility(INVISIBLE); 6298dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Runnable onCompleteRunnable = new Runnable() { 6308dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void run() { 6318dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen child.setVisibility(VISIBLE); 632d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen if (onFinishAnimationRunnable != null) { 633d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onFinishAnimationRunnable.run(); 634d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen } 6358dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6368dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }; 637eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, toScale, toScale, 638d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView); 639557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 640557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung 641d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen public void animateViewIntoPosition(final DragView view, final int fromX, final int fromY, 642ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen final int toX, final int toY, float finalAlpha, float initScaleX, float initScaleY, 643ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float finalScaleX, float finalScaleY, Runnable onCompleteRunnable, 644ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int animationEndStyle, int duration, View anchorView) { 6458dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Rect from = new Rect(fromX, fromY, fromX + 6468dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen view.getMeasuredWidth(), fromY + view.getMeasuredHeight()); 6473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); 648ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen animateView(view, from, to, finalAlpha, initScaleX, initScaleY, finalScaleX, finalScaleY, duration, 649ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen null, null, onCompleteRunnable, animationEndStyle, anchorView); 6503e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 6513e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 652b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen /** 653b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * This method animates a view at the end of a drag and drop animation. 654b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * 655b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param view The view to be animated. This view is drawn directly into DragLayer, and so 656b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * doesn't need to be a child of DragLayer. 657b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param from The initial location of the view. Only the left and top parameters are used. 658b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param to The final location of the view. Only the left and top parameters are used. This 659b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * location doesn't account for scaling, and so should be centered about the desired 660b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * final location (including scaling). 661b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalAlpha The final alpha of the view, in case we want it to fade as it animates. 6626178f13e2d1f0c1a89cea74538b51993ef3439e3Sunny Goyal * @param finalScaleX The final scale of the view. The view is scaled about its center. 6636178f13e2d1f0c1a89cea74538b51993ef3439e3Sunny Goyal * @param finalScaleY The final scale of the view. The view is scaled about its center. 664b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param duration The duration of the animation. 665b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param motionInterpolator The interpolator to use for the location of the view. 666b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param alphaInterpolator The interpolator to use for the alpha of the view. 667b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param onCompleteRunnable Optional runnable to run on animation completion. 6686178f13e2d1f0c1a89cea74538b51993ef3439e3Sunny Goyal * @param animationEndStyle Whether or not to fade out the view once the animation completes. 6696178f13e2d1f0c1a89cea74538b51993ef3439e3Sunny Goyal * {@link #ANIMATION_END_DISAPPEAR} or {@link #ANIMATION_END_REMAIN_VISIBLE}. 6706441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * @param anchorView If not null, this represents the view which the animated view stays 6716441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * anchored to in case scrolling is currently taking place. Note: currently this is 6726441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * only used for the X dimension for the case of the workspace. 673b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen */ 6747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateView(final DragView view, final Rect from, final Rect to, 6757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalAlpha, final float initScaleX, final float initScaleY, 6767bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalScaleX, final float finalScaleY, int duration, 6777bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Interpolator motionInterpolator, final Interpolator alphaInterpolator, 6787bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Runnable onCompleteRunnable, final int animationEndStyle, View anchorView) { 6797bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 680716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Calculate the duration of the animation based on the object's distance 681f7a29e83f06909b378dba39c83a522375682710aSunny Goyal final float dist = (float) Math.hypot(to.left - from.left, to.top - from.top); 682716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final Resources res = getResources(); 683716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); 6843e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 6853e8f811f31a2275e778244427271f77f4116c08bAdam Cohen // If duration < 0, this is a cue to compute the duration based on the distance 6863e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (duration < 0) { 687dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal duration = res.getInteger(R.integer.config_dropAnimMaxDuration); 688dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal if (dist < maxDist) { 689dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist); 6903e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 691dec3a908bfa395095e80e4a532cff98612b624deSunny Goyal duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration)); 692716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 693716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 694043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Fall back to cubic ease out interpolator for the animation if none is specified 695043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung TimeInterpolator interpolator = null; 6963e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (alphaInterpolator == null || motionInterpolator == null) { 697043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung interpolator = mCubicEaseOutInterpolator; 6983e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 699716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 700043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Animate the view 7017bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float initAlpha = view.getAlpha(); 702043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final float dropViewScale = view.getScaleX(); 703043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung AnimatorUpdateListener updateCb = new AnimatorUpdateListener() { 704043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung @Override 705716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 706716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 7077bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int width = view.getMeasuredWidth(); 7087bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int height = view.getMeasuredHeight(); 709716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 7103e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float alphaPercent = alphaInterpolator == null ? percent : 7113e8f811f31a2275e778244427271f77f4116c08bAdam Cohen alphaInterpolator.getInterpolation(percent); 7123e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float motionPercent = motionInterpolator == null ? percent : 7133e8f811f31a2275e778244427271f77f4116c08bAdam Cohen motionInterpolator.getInterpolation(percent); 714a1cdab039292f3d809528c0e2e38580b37864d8dWinson Chung 7157bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleX = initScaleX * dropViewScale; 7167bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleY = initScaleY * dropViewScale; 7177bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX = finalScaleX * percent + initialScaleX * (1 - percent); 7187bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleY = finalScaleY * percent + initialScaleY * (1 - percent); 7197bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float alpha = finalAlpha * alphaPercent + initAlpha * (1 - alphaPercent); 7207bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 7217bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromLeft = from.left + (initialScaleX - 1f) * width / 2; 7227bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromTop = from.top + (initialScaleY - 1f) * height / 2; 7237bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 7247bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent))); 7257bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent))); 7267bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 72728f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen int anchorAdjust = mAnchorView == null ? 0 : (int) (mAnchorView.getScaleX() * 72828f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen (mAnchorViewInitialScrollX - mAnchorView.getScrollX())); 72928f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen 73028f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen int xPos = x - mDropView.getScrollX() + anchorAdjust; 7317bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int yPos = y - mDropView.getScrollY(); 7327bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 7337bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationX(xPos); 7347bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationY(yPos); 7357bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleX(scaleX); 7367bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleY(scaleY); 7377bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setAlpha(alpha); 738716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 739043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung }; 740043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung animateView(view, updateCb, duration, interpolator, onCompleteRunnable, animationEndStyle, 741043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung anchorView); 742043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 743043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 744043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public void animateView(final DragView view, AnimatorUpdateListener updateCb, int duration, 745043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung TimeInterpolator interpolator, final Runnable onCompleteRunnable, 746043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final int animationEndStyle, View anchorView) { 747043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Clean up the previous animations 748043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mDropAnim != null) mDropAnim.cancel(); 749043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 750043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Show the drop view if it was previously hidden 751043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropView = view; 752043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropView.cancelAnimation(); 753d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mDropView.requestLayout(); 754043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 755043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Set the anchor view if the page is scrolling 756043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (anchorView != null) { 757043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mAnchorViewInitialScrollX = anchorView.getScrollX(); 758043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 759043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mAnchorView = anchorView; 760043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 761043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Create and start the animation 762043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim = new ValueAnimator(); 763043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setInterpolator(interpolator); 764043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setDuration(duration); 765043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setFloatValues(0f, 1f); 766043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.addUpdateListener(updateCb); 7673e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropAnim.addListener(new AnimatorListenerAdapter() { 7683e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void onAnimationEnd(Animator animation) { 7698dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if (onCompleteRunnable != null) { 7708dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen onCompleteRunnable.run(); 7718dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 772ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen switch (animationEndStyle) { 773ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_DISAPPEAR: 774ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen clearAnimatedView(); 775ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 776ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_REMAIN_VISIBLE: 777ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 7783e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 7793e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 7803e8f811f31a2275e778244427271f77f4116c08bAdam Cohen }); 781716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.start(); 782716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 783716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 784ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void clearAnimatedView() { 7857bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropAnim != null) { 7867bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropAnim.cancel(); 7877bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 7887bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropView != null) { 7892d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen mDragController.onDeferredEndDrag(mDropView); 7907bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 791ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mDropView = null; 792ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen invalidate(); 793ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 794ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 795ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public View getAnimatedView() { 796ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen return mDropView; 797ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 798ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 799716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen @Override 8008b805b17158886035b38261eb611d8641701ae43Michael Jurka public void onChildViewAdded(View parent, View child) { 801a6d0492e5f0dd4e1b43d4034a770241dc65f8f8cAdam Cohen super.onChildViewAdded(parent, child); 80221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 80321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 80421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 80521b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 8068b805b17158886035b38261eb611d8641701ae43Michael Jurka public void onChildViewRemoved(View parent, View child) { 80721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 80821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 80921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 810432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen @Override 811432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen public void bringChildToFront(View child) { 812432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen super.bringChildToFront(child); 813432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen updateChildIndices(); 814432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } 815432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen 81621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen private void updateChildIndices() { 817432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen mTopViewIndex = -1; 81855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi int childCount = getChildCount(); 81955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi for (int i = 0; i < childCount; i++) { 820b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen if (getChildAt(i) instanceof DragView) { 821432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen mTopViewIndex = i; 82255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 82321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 8242d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen mChildCountOnLastUpdate = childCount; 82521b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 82621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 82721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 82821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen protected int getChildDrawingOrder(int childCount, int i) { 8292d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen if (mChildCountOnLastUpdate != childCount) { 8302d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // between platform versions 17 and 18, behavior for onChildViewRemoved / Added changed. 8312d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // Pre-18, the child was not added / removed by the time of those callbacks. We need to 8322d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // force update our representation of things here to avoid crashing on pre-18 devices 8332d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // in certain instances. 8342d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen updateChildIndices(); 8352d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen } 8362d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen 837432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // i represents the current draw iteration 838432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen if (mTopViewIndex == -1) { 839432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // in general we do nothing 84021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 841432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } else if (i == childCount - 1) { 842432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // if we have a top index, we return it when drawing last item (highest z-order) 843432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen return mTopViewIndex; 844432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } else if (i < mTopViewIndex) { 84521b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 84655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 847432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // for indexes greater than the top index, we fetch one item above to shift for the 848432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // displacement of the top index 849432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen return i + 1; 85021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 85121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 852360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung 85395cdb3a0211650e76adb451588ce89fd585b178fTony Wickham public void invalidateScrim() { 85495cdb3a0211650e76adb451588ce89fd585b178fTony Wickham if (mBackgroundAlpha > 0.0f) { 85595cdb3a0211650e76adb451588ce89fd585b178fTony Wickham invalidate(); 85695cdb3a0211650e76adb451588ce89fd585b178fTony Wickham } 85795cdb3a0211650e76adb451588ce89fd585b178fTony Wickham } 85895cdb3a0211650e76adb451588ce89fd585b178fTony Wickham 859360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung @Override 860360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung protected void dispatchDraw(Canvas canvas) { 8610fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal // Draw the background below children. 8620fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal if (mBackgroundAlpha > 0.0f) { 86395cdb3a0211650e76adb451588ce89fd585b178fTony Wickham // Update the scroll position first to ensure scrim cutout is in the right place. 86495cdb3a0211650e76adb451588ce89fd585b178fTony Wickham mLauncher.getWorkspace().computeScrollWithoutInvalidation(); 86595cdb3a0211650e76adb451588ce89fd585b178fTony Wickham 8666c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen int alpha = (int) (mBackgroundAlpha * 255); 86795cdb3a0211650e76adb451588ce89fd585b178fTony Wickham CellLayout currCellLayout = mLauncher.getWorkspace().getCurrentDragOverlappingLayout(); 86895cdb3a0211650e76adb451588ce89fd585b178fTony Wickham canvas.save(); 86995cdb3a0211650e76adb451588ce89fd585b178fTony Wickham if (currCellLayout != null && currCellLayout != mLauncher.getHotseat().getLayout()) { 87095cdb3a0211650e76adb451588ce89fd585b178fTony Wickham // Cut a hole in the darkening scrim on the page that should be highlighted, if any. 8716178f13e2d1f0c1a89cea74538b51993ef3439e3Sunny Goyal getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect); 87295cdb3a0211650e76adb451588ce89fd585b178fTony Wickham canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE); 87395cdb3a0211650e76adb451588ce89fd585b178fTony Wickham } 8740fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal canvas.drawColor((alpha << 24) | SCRIM_COLOR); 87595cdb3a0211650e76adb451588ce89fd585b178fTony Wickham canvas.restore(); 8766c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 8776c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 8783333b0ced8e6743c41909f6f6b916f1f9ec5a004Sunny Goyal mFocusIndicatorHelper.draw(canvas); 879360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung super.dispatchDraw(canvas); 8808cc05507150fea5282b7581e1a268967a702bcc9Adam Cohen } 881360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung 8826c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen public void setBackgroundAlpha(float alpha) { 8836c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen if (alpha != mBackgroundAlpha) { 8846c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen mBackgroundAlpha = alpha; 8856c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen invalidate(); 8866c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 8876c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 8886c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 8896c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen public float getBackgroundAlpha() { 8906c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen return mBackgroundAlpha; 8916c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 8926c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 89352851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal @Override 89452851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 895740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal View topView = AbstractFloatingView.getTopOpenView(mLauncher); 89652851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal if (topView != null) { 89752851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal return topView.requestFocus(direction, previouslyFocusedRect); 89852851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } else { 89952851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal return super.onRequestFocusInDescendants(direction, previouslyFocusedRect); 90052851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } 90152851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } 90252851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal 90352851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal @Override 90452851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { 905740ac7f00e0b847b8e392800f7948d93493e11d6Sunny Goyal View topView = AbstractFloatingView.getTopOpenView(mLauncher); 90652851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal if (topView != null) { 90752851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal topView.addFocusables(views, direction); 90852851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } else { 90952851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal super.addFocusables(views, direction, focusableMode); 91052851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } 91152851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal } 91252851aa3fd2dd9957e190d779f904f6abaf53fedSunny Goyal 913b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen public void setTouchCompleteListener(TouchCompleteListener listener) { 914b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener = listener; 915b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 916b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen 917b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen public interface TouchCompleteListener { 918b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen public void onTouchComplete(); 919b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 92031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 921