DragLayer.java revision e22172537b9235a5ba41b3054677dd7ed6d89f02
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; 30360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chungimport android.graphics.drawable.Drawable; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 32e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickhamimport android.util.Log; 33d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshevimport android.view.DragEvent; 3426279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.KeyEvent; 3526279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.MotionEvent; 3626279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.View; 3726279c6d0917015eb4e6de0743b79edeea25f9bcDave Hawkeyimport android.view.ViewGroup; 383371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityEvent; 393371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityManager; 40716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.view.animation.DecelerateInterpolator; 413e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.view.animation.Interpolator; 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.FrameLayout; 43ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohenimport android.widget.TextView; 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 45fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.AppWidgetResizeFrame; 46fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.CellLayout; 47fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.InsettableFrameLayout; 48fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.ItemInfo; 49fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Launcher; 50fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.LauncherAppState; 51fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.LauncherAppWidgetHostView; 52dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickhamimport com.android.launcher3.PinchToOverviewListener; 53f9c184a619e4e4b82cf9e0bf318ca6d8deaaaee7Adam Cohenimport com.android.launcher3.R; 54fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.SearchDropTargetBar; 55fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.ShortcutAndWidgetContainer; 56fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Utilities; 57fedca43d396d6fd7c46fbb2f37dfa7cfe3b31834Vadim Tryshevimport com.android.launcher3.Workspace; 5883a8f042adda926489494dff217c15ab696139b4Sunny Goyalimport com.android.launcher3.accessibility.LauncherAccessibilityDelegate; 599c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickhamimport com.android.launcher3.config.FeatureFlags; 60261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.folder.Folder; 61261194387beebaa7927ec4e310274218b651494dSunny Goyalimport com.android.launcher3.folder.FolderIcon; 62091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 63bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 641d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohenimport java.util.ArrayList; 656788269814a678af976dfc7d6135993e172ce586Adam Cohen 6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 670e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * A ViewGroup that coordinates dragging across its descendants 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 69a6d0492e5f0dd4e1b43d4034a770241dc65f8f8cAdam Cohenpublic class DragLayer extends InsettableFrameLayout { 700fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal 71b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal public static final int ANIMATION_END_DISAPPEAR = 0; 72b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal public static final int ANIMATION_END_REMAIN_VISIBLE = 2; 73b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal 740fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal // Scrim color without any alpha component. 750fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal private static final int SCRIM_COLOR = Color.BLACK & 0x00FFFFFF; 760fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal 77b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal private final int[] mTmpXY = new int[2]; 78b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal 79091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk DragController mDragController; 8031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 81716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private int mXDown, mYDown; 82716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private Launcher mLauncher; 83716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 846788269814a678af976dfc7d6135993e172ce586Adam Cohen // Variables relating to resizing widgets 85b135956e95d2d7479290af89d618892ed0e7327dSunny Goyal private final ArrayList<AppWidgetResizeFrame> mResizeFrames = new ArrayList<>(); 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 View mOverlayView; 103432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen private int mTopViewIndex; 1042d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen private int mChildCountOnLastUpdate = -1; 10555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 1066c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen // Darkening scrim 1076c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen private float mBackgroundAlpha = 0; 1086c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 1090f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham // Related to adjacent page hints 1100f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private final Rect mScrollChildPosition = new Rect(); 1110f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private boolean mInScrollArea; 1120f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private boolean mShowPageHints; 1130f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private Drawable mLeftHoverDrawable; 1140f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private Drawable mRightHoverDrawable; 1150f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private Drawable mLeftHoverDrawableActive; 1160f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private Drawable mRightHoverDrawableActive; 1170f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 118dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham // Related to pinch-to-go-to-overview gesture. 1199c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickham private PinchToOverviewListener mPinchListener = null; 12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to create a new DragLayer from XML. 12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1240e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public DragLayer(Context context, AttributeSet attrs) { 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 128be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung 129be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung // Disable multitouch across the workspace/all apps/customize tray 130be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung setMotionEventSplittingEnabled(false); 13121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen setChildrenDrawingOrderEnabled(true); 132360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung 1330f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham final Resources res = getResources(); 1340f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mLeftHoverDrawable = res.getDrawable(R.drawable.page_hover_left); 1350f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mRightHoverDrawable = res.getDrawable(R.drawable.page_hover_right); 1360f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mLeftHoverDrawableActive = res.getDrawable(R.drawable.page_hover_left_active); 1370f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mRightHoverDrawableActive = res.getDrawable(R.drawable.page_hover_right_active); 1380f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mIsRtl = Utilities.isRtl(res); 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1414c98d9235d164680186180974719f551cf935d08Winson Chung public void setup(Launcher launcher, DragController controller) { 1424c98d9235d164680186180974719f551cf935d08Winson Chung mLauncher = launcher; 14300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = controller; 144dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham 145e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham boolean isAccessibilityEnabled = ((AccessibilityManager) mLauncher.getSystemService( 146e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham Context.ACCESSIBILITY_SERVICE)).isEnabled(); 147e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham onAccessibilityStateChanged(isAccessibilityEnabled); 14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean dispatchKeyEvent(KeyEvent event) { 15200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event); 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 155e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham public void onAccessibilityStateChanged(boolean isAccessibilityEnabled) { 156e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham mPinchListener = FeatureFlags.LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW || isAccessibilityEnabled 157e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham ? null : new PinchToOverviewListener(mLauncher); 158e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham } 159e22172537b9235a5ba41b3054677dd7ed6d89f02Tony Wickham 160b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen public void showOverlayView(View overlayView) { 161432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 162b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen mOverlayView = overlayView; 163b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen addView(overlayView, lp); 164b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen 165b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen // ensure that the overlay view stays on top. we can't use drawing order for this 166b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen // because in API level 16 touch dispatch doesn't respect drawing order. 167b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen mOverlayView.bringToFront(); 168432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } 169432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen 170432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen public void dismissOverlayView() { 171432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen removeView(mOverlayView); 172432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } 173432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen 1743371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean isEventOverFolderTextRegion(Folder folder, MotionEvent ev) { 1753371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen getDescendantRectRelativeToSelf(folder.getEditTextRegion(), mHitRect); 1763371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 1773371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1783371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1793371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1803371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1813371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 1823371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private boolean isEventOverFolder(Folder folder, MotionEvent ev) { 1833371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen getDescendantRectRelativeToSelf(folder, mHitRect); 1843371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 1853371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 1863371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1873371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 1883371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 1893371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 190ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal private boolean isEventOverDropTargetBar(MotionEvent ev) { 191006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung getDescendantRectRelativeToSelf(mLauncher.getSearchDropTargetBar(), mHitRect); 192ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 193ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal return true; 194ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 19534d2c915c4762a073b60bb676a9e905392e9679cTony Wickham 19634d2c915c4762a073b60bb676a9e905392e9679cTony Wickham getDescendantRectRelativeToSelf(mLauncher.getAppInfoDropTargetBar(), mHitRect); 19734d2c915c4762a073b60bb676a9e905392e9679cTony Wickham if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) { 19834d2c915c4762a073b60bb676a9e905392e9679cTony Wickham return true; 19934d2c915c4762a073b60bb676a9e905392e9679cTony Wickham } 200ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal return false; 201ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 202ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 20376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean handleTouchDown(MotionEvent ev, boolean intercept) { 2046788269814a678af976dfc7d6135993e172ce586Adam Cohen Rect hitRect = new Rect(); 2056788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 2066788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 2076788269814a678af976dfc7d6135993e172ce586Adam Cohen 2086788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame child: mResizeFrames) { 2096788269814a678af976dfc7d6135993e172ce586Adam Cohen child.getHitRect(hitRect); 2106788269814a678af976dfc7d6135993e172ce586Adam Cohen if (hitRect.contains(x, y)) { 2116788269814a678af976dfc7d6135993e172ce586Adam Cohen if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) { 2126788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = child; 2136788269814a678af976dfc7d6135993e172ce586Adam Cohen mXDown = x; 2146788269814a678af976dfc7d6135993e172ce586Adam Cohen mYDown = y; 2156788269814a678af976dfc7d6135993e172ce586Adam Cohen requestDisallowInterceptTouchEvent(true); 2166788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 2176788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2186788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2196788269814a678af976dfc7d6135993e172ce586Adam Cohen } 22076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 2211d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 222424418bb50ccf5d9270650b70cc51f423da51a65Sunny Goyal if (currentFolder != null && intercept) { 2231d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen if (currentFolder.isEditingName()) { 2243371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isEventOverFolderTextRegion(currentFolder, ev)) { 2251d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen currentFolder.dismissEditingName(); 22676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 2272801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 2282801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 22976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 2303371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (!isEventOverFolder(currentFolder, ev)) { 231ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (isInAccessibleDrag()) { 232ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal // Do not close the folder if in drag and drop. 233ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (!isEventOverDropTargetBar(ev)) { 234ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal return true; 235ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 236ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } else { 237ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal mLauncher.closeFolder(); 238ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal return true; 239ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 24076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 2412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 2426788269814a678af976dfc7d6135993e172ce586Adam Cohen return false; 2436788269814a678af976dfc7d6135993e172ce586Adam Cohen } 2446788269814a678af976dfc7d6135993e172ce586Adam Cohen 24531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 24631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent ev) { 247b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen int action = ev.getAction(); 248b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen 249b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (action == MotionEvent.ACTION_DOWN) { 25076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (handleTouchDown(ev, true)) { 2516788269814a678af976dfc7d6135993e172ce586Adam Cohen return true; 252d1837cc69eb222371afdd30890f7215d117510f2Patrick Dubroy } 253b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 254b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (mTouchCompleteListener != null) { 255b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener.onTouchComplete(); 256b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 257b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener = null; 2581b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen } 2596788269814a678af976dfc7d6135993e172ce586Adam Cohen clearAllResizeFrames(); 260dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham 2619c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickham if (mPinchListener != null && mPinchListener.onInterceptTouchEvent(ev)) { 262c5b31965d9bcb4c9899e2d1c45b5c95c70bac9f2Tony Wickham // Stop listening for scrolling etc. (onTouchEvent() handles the rest of the pinch.) 263c5b31965d9bcb4c9899e2d1c45b5c95c70bac9f2Tony Wickham return true; 264dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham } 2654db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onInterceptTouchEvent(ev); 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 2693371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onInterceptHoverEvent(MotionEvent ev) { 270023c71eb3b2bbe63272cb74baaf050c4188c89b0Michael Jurka if (mLauncher == null || mLauncher.getWorkspace() == null) { 271023c71eb3b2bbe63272cb74baaf050c4188c89b0Michael Jurka return false; 272023c71eb3b2bbe63272cb74baaf050c4188c89b0Michael Jurka } 2733371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 2743371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (currentFolder == null) { 2753371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 2763371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } else { 2778b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 2788b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 2798b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isTouchExplorationEnabled()) { 2803371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen final int action = ev.getAction(); 281ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal boolean isOverFolderOrSearchBar; 2823371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen switch (action) { 2833371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_ENTER: 284ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) || 285ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal (isInAccessibleDrag() && isEventOverDropTargetBar(ev)); 286ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (!isOverFolderOrSearchBar) { 2873371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 2883371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 2893371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 2903371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 291693fbc7f1737d89f11f9ab81558c109f0883ab0eMihail Dumitrescu mHoverPointClosesFolder = false; 292693fbc7f1737d89f11f9ab81558c109f0883ab0eMihail Dumitrescu break; 2933371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen case MotionEvent.ACTION_HOVER_MOVE: 294ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) || 295ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal (isInAccessibleDrag() && isEventOverDropTargetBar(ev)); 296ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (!isOverFolderOrSearchBar && !mHoverPointClosesFolder) { 2973371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName()); 2983371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mHoverPointClosesFolder = true; 2993371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 300ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } else if (!isOverFolderOrSearchBar) { 3013371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 3023371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 303693fbc7f1737d89f11f9ab81558c109f0883ab0eMihail Dumitrescu mHoverPointClosesFolder = false; 3043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3053371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3063371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3073371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 3083371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3093371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 3103371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private void sendTapOutsideFolderAccessibilityEvent(boolean isEditingName) { 3118b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 3128b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 3138b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isEnabled()) { 3143371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen int stringId = isEditingName ? R.string.folder_tap_to_rename : R.string.folder_tap_to_close; 3153371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent event = AccessibilityEvent.obtain( 3163371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent.TYPE_VIEW_FOCUSED); 3173371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen onInitializeAccessibilityEvent(event); 3188b805b17158886035b38261eb611d8641701ae43Michael Jurka event.getText().add(getContext().getString(stringId)); 3198b805b17158886035b38261eb611d8641701ae43Michael Jurka accessibilityManager.sendAccessibilityEvent(event); 3203371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 32183ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 32283ca480941b3dd635b62347008fc8d7859d82002Winson Chung 323ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal private boolean isInAccessibleDrag() { 324ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal LauncherAccessibilityDelegate delegate = LauncherAppState 325ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal .getInstance().getAccessibilityDelegate(); 326ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal return delegate != null && delegate.isInAccessibleDrag(); 327ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 328ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 32983ca480941b3dd635b62347008fc8d7859d82002Winson Chung @Override 33083ca480941b3dd635b62347008fc8d7859d82002Winson Chung public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) { 33183ca480941b3dd635b62347008fc8d7859d82002Winson Chung Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 33283ca480941b3dd635b62347008fc8d7859d82002Winson Chung if (currentFolder != null) { 33383ca480941b3dd635b62347008fc8d7859d82002Winson Chung if (child == currentFolder) { 33483ca480941b3dd635b62347008fc8d7859d82002Winson Chung return super.onRequestSendAccessibilityEvent(child, event); 33583ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 336ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 337ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (isInAccessibleDrag() && child instanceof SearchDropTargetBar) { 338ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal return super.onRequestSendAccessibilityEvent(child, event); 339ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 34083ca480941b3dd635b62347008fc8d7859d82002Winson Chung // Skip propagating onRequestSendAccessibilityEvent all for other children 34183ca480941b3dd635b62347008fc8d7859d82002Winson Chung // when a folder is open 34283ca480941b3dd635b62347008fc8d7859d82002Winson Chung return false; 34383ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 34483ca480941b3dd635b62347008fc8d7859d82002Winson Chung return super.onRequestSendAccessibilityEvent(child, event); 34583ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 34683ca480941b3dd635b62347008fc8d7859d82002Winson Chung 34783ca480941b3dd635b62347008fc8d7859d82002Winson Chung @Override 34883ca480941b3dd635b62347008fc8d7859d82002Winson Chung public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) { 34983ca480941b3dd635b62347008fc8d7859d82002Winson Chung Folder currentFolder = mLauncher.getWorkspace().getOpenFolder(); 35083ca480941b3dd635b62347008fc8d7859d82002Winson Chung if (currentFolder != null) { 35183ca480941b3dd635b62347008fc8d7859d82002Winson Chung // Only add the folder as a child for accessibility when it is open 35283ca480941b3dd635b62347008fc8d7859d82002Winson Chung childrenForAccessibility.add(currentFolder); 353ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal 354ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal if (isInAccessibleDrag()) { 355006ee269ba2e9946a83b42f96d4a0296254cba4aWinson Chung childrenForAccessibility.add(mLauncher.getSearchDropTargetBar()); 35634d2c915c4762a073b60bb676a9e905392e9679cTony Wickham childrenForAccessibility.add(mLauncher.getAppInfoDropTargetBar()); 357ccc414bb1e18206d2a3d8d797070278bdb286354Sunny Goyal } 35883ca480941b3dd635b62347008fc8d7859d82002Winson Chung } else { 35983ca480941b3dd635b62347008fc8d7859d82002Winson Chung super.addChildrenForAccessibility(childrenForAccessibility); 36083ca480941b3dd635b62347008fc8d7859d82002Winson Chung } 3613371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3623371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 3633371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 3643371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean onHoverEvent(MotionEvent ev) { 3653371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // If we've received this, we've already done the necessary handling 3663371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // in onInterceptHoverEvent. Return true to consume the event. 3673371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return false; 3683371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3693371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 3703371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 37131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 3726788269814a678af976dfc7d6135993e172ce586Adam Cohen boolean handled = false; 3736788269814a678af976dfc7d6135993e172ce586Adam Cohen int action = ev.getAction(); 3746788269814a678af976dfc7d6135993e172ce586Adam Cohen 3756788269814a678af976dfc7d6135993e172ce586Adam Cohen int x = (int) ev.getX(); 3766788269814a678af976dfc7d6135993e172ce586Adam Cohen int y = (int) ev.getY(); 3776788269814a678af976dfc7d6135993e172ce586Adam Cohen 378dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham // This is only reached if a pinch was started from onInterceptTouchEvent(); 379dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham // this continues sending events for it. 3809c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickham if (mPinchListener != null) { 3819c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickham mPinchListener.onTouchEvent(ev); 3829c43182ff1d095b1bbaacedefe6e0f4c2deb17e3Tony Wickham } 383dadb304b4682998c43b9c07bef45b9a9380f3287Tony Wickham 384b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (action == MotionEvent.ACTION_DOWN) { 385b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (handleTouchDown(ev, false)) { 386b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen return true; 387b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 388b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 389b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen if (mTouchCompleteListener != null) { 390b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener.onTouchComplete(); 3916788269814a678af976dfc7d6135993e172ce586Adam Cohen } 392b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener = null; 3936788269814a678af976dfc7d6135993e172ce586Adam Cohen } 3946788269814a678af976dfc7d6135993e172ce586Adam Cohen 3956788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mCurrentResizeFrame != null) { 3966788269814a678af976dfc7d6135993e172ce586Adam Cohen handled = true; 3976788269814a678af976dfc7d6135993e172ce586Adam Cohen switch (action) { 3986788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_MOVE: 3996788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); 4006788269814a678af976dfc7d6135993e172ce586Adam Cohen break; 4016788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_CANCEL: 4026788269814a678af976dfc7d6135993e172ce586Adam Cohen case MotionEvent.ACTION_UP: 403bebf042666cffe52039b875a549a582abd78a431Adam Cohen mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown); 404bebf042666cffe52039b875a549a582abd78a431Adam Cohen mCurrentResizeFrame.onTouchUp(); 4056788269814a678af976dfc7d6135993e172ce586Adam Cohen mCurrentResizeFrame = null; 4066788269814a678af976dfc7d6135993e172ce586Adam Cohen } 4076788269814a678af976dfc7d6135993e172ce586Adam Cohen } 4086788269814a678af976dfc7d6135993e172ce586Adam Cohen if (handled) return true; 4094db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato return mDragController.onTouchEvent(ev); 41091a9c9636f10f1e12cd1f660b2e330634fbdc7dcRomain Guy } 411ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy 412d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev @Override 413d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev public boolean onDragEvent (DragEvent event) { 414d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev return mDragController.onDragEvent(event); 415d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev } 416d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev 41735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 41835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Determine the rect of the descendant in this DragLayer's coordinates 41935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 42035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant whose coordinates we want to find. 42135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param r The rect into which to place the results. 42235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. 42335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 424ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen public float getDescendantRectRelativeToSelf(View descendant, Rect r) { 425716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[0] = 0; 426716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mTmpXY[1] = 0; 427ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen float scale = getDescendantCoordRelativeToSelf(descendant, mTmpXY); 4287d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen 4298dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen r.set(mTmpXY[0], mTmpXY[1], 4307d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen (int) (mTmpXY[0] + scale * descendant.getMeasuredWidth()), 4317d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen (int) (mTmpXY[1] + scale * descendant.getMeasuredHeight())); 432ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen return scale; 433716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 43476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 435307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen public float getLocationInDragLayer(View child, int[] loc) { 43635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[0] = 0; 43735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen loc[1] = 0; 438307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen return getDescendantCoordRelativeToSelf(child, loc); 43935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 44035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 4417d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public float getDescendantCoordRelativeToSelf(View descendant, int[] coord) { 4427d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen return getDescendantCoordRelativeToSelf(descendant, coord, false); 4437d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen } 4447d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen 44535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen /** 44635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * Given a coordinate relative to the descendant, find the coordinate in this DragLayer's 44735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * coordinates. 44835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * 44935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param descendant The descendant to which the passed coordinate is relative. 45035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen * @param coord The coordinate that we want mapped. 4517d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen * @param includeRootScroll Whether or not to account for the scroll of the root descendant: 4527d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen * sometimes this is relevant as in a child's coordinates within the root descendant. 453307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen * @return The factor by which this descendant is scaled relative to this DragLayer. Caution 454307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen * this scale factor is assumed to be equal in X and Y, and so if at any point this 455307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen * assumption fails, we will need to return a pair of scale factors. 45635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen */ 4577d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public float getDescendantCoordRelativeToSelf(View descendant, int[] coord, 4587d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen boolean includeRootScroll) { 459c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung return Utilities.getDescendantCoordRelativeToParent(descendant, this, 460c9ca2980983ab21fc8631c7a65399d6d9c70f39cWinson Chung coord, includeRootScroll); 461c9ca2980983ab21fc8631c7a65399d6d9c70f39cWinson Chung } 462c9ca2980983ab21fc8631c7a65399d6d9c70f39cWinson Chung 4637d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen /** 4647d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen * Inverse of {@link #getDescendantCoordRelativeToSelf(View, int[])}. 4657d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen */ 4667d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public float mapCoordInSelfToDescendent(View descendant, int[] coord) { 467c763c4e4d28c256d1368be3fc1c4526c8b9bd232Winson Chung return Utilities.mapCoordInSelfToDescendent(descendant, this, coord); 46876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 46976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 4703e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void getViewRectRelativeToSelf(View v, Rect r) { 4713e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int[] loc = new int[2]; 4728dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen getLocationInWindow(loc); 4733e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int x = loc[0]; 4743e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int y = loc[1]; 475716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4768dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen v.getLocationInWindow(loc); 4773e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vX = loc[0]; 4783e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int vY = loc[1]; 479716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 4803e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int left = vX - x; 4813e8f811f31a2275e778244427271f77f4116c08bAdam Cohen int top = vY - y; 4823e8f811f31a2275e778244427271f77f4116c08bAdam Cohen r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight()); 483716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 484716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 485ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy @Override 486ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy public boolean dispatchUnhandledMove(View focused, int direction) { 487ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy return mDragController.dispatchUnhandledMove(focused, direction); 488ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy } 489120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen 490bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 491bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public LayoutParams generateLayoutParams(AttributeSet attrs) { 492bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return new LayoutParams(getContext(), attrs); 493bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 494bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 495bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 496bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen protected LayoutParams generateDefaultLayoutParams() { 497bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 498bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 499bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 500bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen // Override to allow type-checking of LayoutParams. 501bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 502bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 503bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return p instanceof LayoutParams; 504bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 505bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 506bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen @Override 507bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 508bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen return new LayoutParams(p); 509bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 510bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 511bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public static class LayoutParams extends InsettableFrameLayout.LayoutParams { 5126788269814a678af976dfc7d6135993e172ce586Adam Cohen public int x, y; 5136788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean customPosition = false; 5146788269814a678af976dfc7d6135993e172ce586Adam Cohen 515bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public LayoutParams(Context c, AttributeSet attrs) { 516bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen super(c, attrs); 517bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 518bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 5196788269814a678af976dfc7d6135993e172ce586Adam Cohen public LayoutParams(int width, int height) { 5206788269814a678af976dfc7d6135993e172ce586Adam Cohen super(width, height); 5216788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5226788269814a678af976dfc7d6135993e172ce586Adam Cohen 523bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen public LayoutParams(ViewGroup.LayoutParams lp) { 524bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen super(lp); 525bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen } 526bc927f9c24001e250622ca9a2547ee5b65baef58Adam Cohen 5276788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setWidth(int width) { 5286788269814a678af976dfc7d6135993e172ce586Adam Cohen this.width = width; 5296788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5306788269814a678af976dfc7d6135993e172ce586Adam Cohen 5316788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getWidth() { 5326788269814a678af976dfc7d6135993e172ce586Adam Cohen return width; 5336788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5346788269814a678af976dfc7d6135993e172ce586Adam Cohen 5356788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setHeight(int height) { 5366788269814a678af976dfc7d6135993e172ce586Adam Cohen this.height = height; 5376788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5386788269814a678af976dfc7d6135993e172ce586Adam Cohen 5396788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getHeight() { 5406788269814a678af976dfc7d6135993e172ce586Adam Cohen return height; 5416788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5426788269814a678af976dfc7d6135993e172ce586Adam Cohen 5436788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setX(int x) { 5446788269814a678af976dfc7d6135993e172ce586Adam Cohen this.x = x; 5456788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5466788269814a678af976dfc7d6135993e172ce586Adam Cohen 5476788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getX() { 5486788269814a678af976dfc7d6135993e172ce586Adam Cohen return x; 5496788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5506788269814a678af976dfc7d6135993e172ce586Adam Cohen 5516788269814a678af976dfc7d6135993e172ce586Adam Cohen public void setY(int y) { 5526788269814a678af976dfc7d6135993e172ce586Adam Cohen this.y = y; 5536788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5546788269814a678af976dfc7d6135993e172ce586Adam Cohen 5556788269814a678af976dfc7d6135993e172ce586Adam Cohen public int getY() { 5566788269814a678af976dfc7d6135993e172ce586Adam Cohen return y; 5576788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5586788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5596788269814a678af976dfc7d6135993e172ce586Adam Cohen 5606788269814a678af976dfc7d6135993e172ce586Adam Cohen protected void onLayout(boolean changed, int l, int t, int r, int b) { 5616788269814a678af976dfc7d6135993e172ce586Adam Cohen super.onLayout(changed, l, t, r, b); 5626788269814a678af976dfc7d6135993e172ce586Adam Cohen int count = getChildCount(); 5636788269814a678af976dfc7d6135993e172ce586Adam Cohen for (int i = 0; i < count; i++) { 5646788269814a678af976dfc7d6135993e172ce586Adam Cohen View child = getChildAt(i); 5656788269814a678af976dfc7d6135993e172ce586Adam Cohen final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams(); 5666788269814a678af976dfc7d6135993e172ce586Adam Cohen if (flp instanceof LayoutParams) { 5676788269814a678af976dfc7d6135993e172ce586Adam Cohen final LayoutParams lp = (LayoutParams) flp; 5686788269814a678af976dfc7d6135993e172ce586Adam Cohen if (lp.customPosition) { 5696788269814a678af976dfc7d6135993e172ce586Adam Cohen child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height); 5706788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5716788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5726788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5736788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5746788269814a678af976dfc7d6135993e172ce586Adam Cohen 5756788269814a678af976dfc7d6135993e172ce586Adam Cohen public void clearAllResizeFrames() { 5766788269814a678af976dfc7d6135993e172ce586Adam Cohen if (mResizeFrames.size() > 0) { 5776788269814a678af976dfc7d6135993e172ce586Adam Cohen for (AppWidgetResizeFrame frame: mResizeFrames) { 578bebf042666cffe52039b875a549a582abd78a431Adam Cohen frame.commitResize(); 5796788269814a678af976dfc7d6135993e172ce586Adam Cohen removeView(frame); 5806788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5816788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.clear(); 5826788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5836788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5846788269814a678af976dfc7d6135993e172ce586Adam Cohen 5856788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean hasResizeFrames() { 5866788269814a678af976dfc7d6135993e172ce586Adam Cohen return mResizeFrames.size() > 0; 5876788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5886788269814a678af976dfc7d6135993e172ce586Adam Cohen 5896788269814a678af976dfc7d6135993e172ce586Adam Cohen public boolean isWidgetBeingResized() { 5906788269814a678af976dfc7d6135993e172ce586Adam Cohen return mCurrentResizeFrame != null; 5916788269814a678af976dfc7d6135993e172ce586Adam Cohen } 5926788269814a678af976dfc7d6135993e172ce586Adam Cohen 5936788269814a678af976dfc7d6135993e172ce586Adam Cohen public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget, 5946788269814a678af976dfc7d6135993e172ce586Adam Cohen CellLayout cellLayout) { 5956788269814a678af976dfc7d6135993e172ce586Adam Cohen AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(), 5963a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka widget, cellLayout, this); 5976788269814a678af976dfc7d6135993e172ce586Adam Cohen 5986788269814a678af976dfc7d6135993e172ce586Adam Cohen LayoutParams lp = new LayoutParams(-1, -1); 5996788269814a678af976dfc7d6135993e172ce586Adam Cohen lp.customPosition = true; 6006788269814a678af976dfc7d6135993e172ce586Adam Cohen 6016788269814a678af976dfc7d6135993e172ce586Adam Cohen addView(resizeFrame, lp); 6026788269814a678af976dfc7d6135993e172ce586Adam Cohen mResizeFrames.add(resizeFrame); 6036788269814a678af976dfc7d6135993e172ce586Adam Cohen 6046788269814a678af976dfc7d6135993e172ce586Adam Cohen resizeFrame.snapToWidget(false); 6056788269814a678af976dfc7d6135993e172ce586Adam Cohen } 606716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 6077bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateViewIntoPosition(DragView dragView, final int[] pos, float alpha, 6087bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX, float scaleY, int animationEndStyle, Runnable onFinishRunnable, 6097bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int duration) { 610b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen Rect r = new Rect(); 611b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen getViewRectRelativeToSelf(dragView, r); 612b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromX = r.left; 613b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen final int fromY = r.top; 614b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen 6157bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung animateViewIntoPosition(dragView, fromX, fromY, pos[0], pos[1], alpha, 1, 1, scaleX, scaleY, 616ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen onFinishRunnable, animationEndStyle, duration, null); 617ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 618ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 619557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung public void animateViewIntoPosition(DragView dragView, final View child, 62028f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen final Runnable onFinishAnimationRunnable, View anchorView) { 62128f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen animateViewIntoPosition(dragView, child, -1, onFinishAnimationRunnable, anchorView); 622ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen } 623ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen 624ed51cc9a12c50d12e7d30ed209a49f1a40858043Adam Cohen public void animateViewIntoPosition(DragView dragView, final View child, int duration, 6256441de0ec2a71862798dd51180d0811b42edd514Adam Cohen final Runnable onFinishAnimationRunnable, View anchorView) { 626a52570f8f9ad65b85e33a2f2e87722f9edd6c6f4Michael Jurka ShortcutAndWidgetContainer parentChildren = (ShortcutAndWidgetContainer) child.getParent(); 627716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 628eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung parentChildren.measureChild(child); 629716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 6303e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect r = new Rect(); 6313e8f811f31a2275e778244427271f77f4116c08bAdam Cohen getViewRectRelativeToSelf(dragView, r); 632716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 633716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen int coord[] = new int[2]; 634307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen float childScale = child.getScaleX(); 635307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen coord[0] = lp.x + (int) (child.getMeasuredWidth() * (1 - childScale) / 2); 636307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen coord[1] = lp.y + (int) (child.getMeasuredHeight() * (1 - childScale) / 2); 637eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung 6388dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen // Since the child hasn't necessarily been laid out, we force the lp to be updated with 639ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen // the correct coordinates (above) and use these to determine the final location 640557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung float scale = getDescendantCoordRelativeToSelf((View) child.getParent(), coord); 641307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen // We need to account for the scale of the child itself, as the above only accounts for 642307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen // for the scale in parents. 643307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen scale *= childScale; 644ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toX = coord[0]; 645ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen int toY = coord[1]; 646eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung float toScale = scale; 6474497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn if (child instanceof TextView) { 6484497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn TextView tv = (TextView) child; 649eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // Account for the source scale of the icon (ie. from AllApps to Workspace, in which 650eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung // the workspace may have smaller icon bounds). 651eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung toScale = scale / dragView.getIntrinsicIconScaleFactor(); 6524497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn 6534497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn // The child may be scaled (always about the center of the view) so to account for it, 6544497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn // we have to offset the position by the scaled size. Once we do that, we can center 6554497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn // the drag view about the scaled child view. 656eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung toY += Math.round(toScale * tv.getPaddingTop()); 657eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung toY -= dragView.getMeasuredHeight() * (1 - toScale) / 2; 65895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal if (dragView.getDragVisualizeOffset() != null) { 65995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal toY -= Math.round(toScale * dragView.getDragVisualizeOffset().y); 66095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal } 66195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal 6624497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 6634497ebf9a2726e2a7dbb7f3c49389308908f8454Andrew Flynn } else if (child instanceof FolderIcon) { 664ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Account for holographic blur padding on the drag view 6655f8afe6280eae34620067696173e71943e1a30a3Winson Chung toY += Math.round(scale * (child.getPaddingTop() - dragView.getDragRegionTop())); 666307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen toY -= scale * Workspace.DRAG_BITMAP_PADDING / 2; 667307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen toY -= (1 - scale) * dragView.getMeasuredHeight() / 2; 668ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung // Center in the x coordinate about the target's drawable 669ea359c6aee44c0fe3bb94f7002c3b49208b32b7fWinson Chung toX -= (dragView.getMeasuredWidth() - Math.round(scale * child.getMeasuredWidth())) / 2; 670ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } else { 671ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toY -= (Math.round(scale * (dragView.getHeight() - child.getMeasuredHeight()))) / 2; 672ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen toX -= (Math.round(scale * (dragView.getMeasuredWidth() 673ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen - child.getMeasuredWidth()))) / 2; 674ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen } 675716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 676ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromX = r.left; 677ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen final int fromY = r.top; 678716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen child.setVisibility(INVISIBLE); 6798dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Runnable onCompleteRunnable = new Runnable() { 6808dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void run() { 6818dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen child.setVisibility(VISIBLE); 682d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen if (onFinishAnimationRunnable != null) { 683d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onFinishAnimationRunnable.run(); 684d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen } 6858dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 6868dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen }; 687eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung animateViewIntoPosition(dragView, fromX, fromY, toX, toY, 1, 1, 1, toScale, toScale, 688d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen onCompleteRunnable, ANIMATION_END_DISAPPEAR, duration, anchorView); 689557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung } 690557d6ed50cc6560163440aa134870ef0bb11415bWinson Chung 691d41fbf5680750e34335bba6b38298186c144a4b7Adam Cohen public void animateViewIntoPosition(final DragView view, final int fromX, final int fromY, 692ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen final int toX, final int toY, float finalAlpha, float initScaleX, float initScaleY, 693ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen float finalScaleX, float finalScaleY, Runnable onCompleteRunnable, 694ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen int animationEndStyle, int duration, View anchorView) { 6958dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen Rect from = new Rect(fromX, fromY, fromX + 6968dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen view.getMeasuredWidth(), fromY + view.getMeasuredHeight()); 6973e8f811f31a2275e778244427271f77f4116c08bAdam Cohen Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight()); 698ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen animateView(view, from, to, finalAlpha, initScaleX, initScaleY, finalScaleX, finalScaleY, duration, 699ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen null, null, onCompleteRunnable, animationEndStyle, anchorView); 7003e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 7013e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 702b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen /** 703b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * This method animates a view at the end of a drag and drop animation. 704b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * 705b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param view The view to be animated. This view is drawn directly into DragLayer, and so 706b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * doesn't need to be a child of DragLayer. 707b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param from The initial location of the view. Only the left and top parameters are used. 708b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param to The final location of the view. Only the left and top parameters are used. This 709b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * location doesn't account for scaling, and so should be centered about the desired 710b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * final location (including scaling). 711b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalAlpha The final alpha of the view, in case we want it to fade as it animates. 712b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param finalScale The final scale of the view. The view is scaled about its center. 713b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param duration The duration of the animation. 714b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param motionInterpolator The interpolator to use for the location of the view. 715b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param alphaInterpolator The interpolator to use for the alpha of the view. 716b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param onCompleteRunnable Optional runnable to run on animation completion. 717b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * @param fadeOut Whether or not to fade out the view once the animation completes. If true, 718b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen * the runnable will execute after the view is faded out. 7196441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * @param anchorView If not null, this represents the view which the animated view stays 7206441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * anchored to in case scrolling is currently taking place. Note: currently this is 7216441de0ec2a71862798dd51180d0811b42edd514Adam Cohen * only used for the X dimension for the case of the workspace. 722b7e1618c627c6471c565f4f599228648d9e70a10Adam Cohen */ 7237bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung public void animateView(final DragView view, final Rect from, final Rect to, 7247bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalAlpha, final float initScaleX, final float initScaleY, 7257bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float finalScaleX, final float finalScaleY, int duration, 7267bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Interpolator motionInterpolator, final Interpolator alphaInterpolator, 7277bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final Runnable onCompleteRunnable, final int animationEndStyle, View anchorView) { 7287bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 729716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen // Calculate the duration of the animation based on the object's distance 730f7a29e83f06909b378dba39c83a522375682710aSunny Goyal final float dist = (float) Math.hypot(to.left - from.left, to.top - from.top); 731716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final Resources res = getResources(); 732716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); 7333e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 7343e8f811f31a2275e778244427271f77f4116c08bAdam Cohen // If duration < 0, this is a cue to compute the duration based on the distance 7353e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (duration < 0) { 7363e8f811f31a2275e778244427271f77f4116c08bAdam Cohen duration = res.getInteger(R.integer.config_dropAnimMaxDuration); 7373e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (dist < maxDist) { 7388dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist); 7393e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 74061b0c69d3fe331d3de338322396d5de691d58613Winson Chung duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration)); 741716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 742716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 743043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Fall back to cubic ease out interpolator for the animation if none is specified 744043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung TimeInterpolator interpolator = null; 7453e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (alphaInterpolator == null || motionInterpolator == null) { 746043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung interpolator = mCubicEaseOutInterpolator; 7473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 748716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 749043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Animate the view 7507bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final float initAlpha = view.getAlpha(); 751043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final float dropViewScale = view.getScaleX(); 752043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung AnimatorUpdateListener updateCb = new AnimatorUpdateListener() { 753043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung @Override 754716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 755716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen final float percent = (Float) animation.getAnimatedValue(); 7567bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int width = view.getMeasuredWidth(); 7577bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung final int height = view.getMeasuredHeight(); 758716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 7593e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float alphaPercent = alphaInterpolator == null ? percent : 7603e8f811f31a2275e778244427271f77f4116c08bAdam Cohen alphaInterpolator.getInterpolation(percent); 7613e8f811f31a2275e778244427271f77f4116c08bAdam Cohen float motionPercent = motionInterpolator == null ? percent : 7623e8f811f31a2275e778244427271f77f4116c08bAdam Cohen motionInterpolator.getInterpolation(percent); 763a1cdab039292f3d809528c0e2e38580b37864d8dWinson Chung 7647bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleX = initScaleX * dropViewScale; 7657bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float initialScaleY = initScaleY * dropViewScale; 7667bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleX = finalScaleX * percent + initialScaleX * (1 - percent); 7677bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float scaleY = finalScaleY * percent + initialScaleY * (1 - percent); 7687bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float alpha = finalAlpha * alphaPercent + initAlpha * (1 - alphaPercent); 7697bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 7707bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromLeft = from.left + (initialScaleX - 1f) * width / 2; 7717bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung float fromTop = from.top + (initialScaleY - 1f) * height / 2; 7727bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 7737bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int x = (int) (fromLeft + Math.round(((to.left - fromLeft) * motionPercent))); 7747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int y = (int) (fromTop + Math.round(((to.top - fromTop) * motionPercent))); 7757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 77628f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen int anchorAdjust = mAnchorView == null ? 0 : (int) (mAnchorView.getScaleX() * 77728f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen (mAnchorViewInitialScrollX - mAnchorView.getScrollX())); 77828f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen 77928f852ab678d9750879b6d3549bf5da176cf1225Adam Cohen int xPos = x - mDropView.getScrollX() + anchorAdjust; 7807bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung int yPos = y - mDropView.getScrollY(); 7817bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung 7827bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationX(xPos); 7837bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setTranslationY(yPos); 7847bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleX(scaleX); 7857bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setScaleY(scaleY); 7867bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropView.setAlpha(alpha); 787716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 788043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung }; 789043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung animateView(view, updateCb, duration, interpolator, onCompleteRunnable, animationEndStyle, 790043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung anchorView); 791043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 792043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 793043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public void animateView(final DragView view, AnimatorUpdateListener updateCb, int duration, 794043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung TimeInterpolator interpolator, final Runnable onCompleteRunnable, 795043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung final int animationEndStyle, View anchorView) { 796043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Clean up the previous animations 797043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (mDropAnim != null) mDropAnim.cancel(); 798043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 799043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Show the drop view if it was previously hidden 800043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropView = view; 801043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropView.cancelAnimation(); 802d6c8e7eeb13094ea1349897663ae28d8a3bf2773Vadim Tryshev mDropView.requestLayout(); 803043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 804043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Set the anchor view if the page is scrolling 805043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung if (anchorView != null) { 806043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mAnchorViewInitialScrollX = anchorView.getScrollX(); 807043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 808043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mAnchorView = anchorView; 809043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 810043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung // Create and start the animation 811043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim = new ValueAnimator(); 812043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setInterpolator(interpolator); 813043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setDuration(duration); 814043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.setFloatValues(0f, 1f); 815043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung mDropAnim.addUpdateListener(updateCb); 8163e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mDropAnim.addListener(new AnimatorListenerAdapter() { 8173e8f811f31a2275e778244427271f77f4116c08bAdam Cohen public void onAnimationEnd(Animator animation) { 8188dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if (onCompleteRunnable != null) { 8198dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen onCompleteRunnable.run(); 8208dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 821ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen switch (animationEndStyle) { 822ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_DISAPPEAR: 823ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen clearAnimatedView(); 824ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 825ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen case ANIMATION_END_REMAIN_VISIBLE: 826ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen break; 8273e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 8283e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 8293e8f811f31a2275e778244427271f77f4116c08bAdam Cohen }); 830716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mDropAnim.start(); 831716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen } 832716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen 833ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public void clearAnimatedView() { 8347bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropAnim != null) { 8357bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung mDropAnim.cancel(); 8367bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 8377bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung if (mDropView != null) { 8382d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen mDragController.onDeferredEndDrag(mDropView); 8397bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung } 840ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen mDropView = null; 841ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen invalidate(); 842ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 843ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 844ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen public View getAnimatedView() { 845ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen return mDropView; 846ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen } 847ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen 848716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen @Override 8498b805b17158886035b38261eb611d8641701ae43Michael Jurka public void onChildViewAdded(View parent, View child) { 850a6d0492e5f0dd4e1b43d4034a770241dc65f8f8cAdam Cohen super.onChildViewAdded(parent, child); 851b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen if (mOverlayView != null) { 852b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen // ensure that the overlay view stays on top. we can't use drawing order for this 853b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen // because in API level 16 touch dispatch doesn't respect drawing order. 854b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen mOverlayView.bringToFront(); 855b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen } 85621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 85721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 85821b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 85921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 8608b805b17158886035b38261eb611d8641701ae43Michael Jurka public void onChildViewRemoved(View parent, View child) { 86121b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen updateChildIndices(); 86221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 86321b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 864432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen @Override 865432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen public void bringChildToFront(View child) { 866432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen super.bringChildToFront(child); 867b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen if (child != mOverlayView && mOverlayView != null) { 868b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen // ensure that the overlay view stays on top. we can't use drawing order for this 869b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen // because in API level 16 touch dispatch doesn't respect drawing order. 870b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen mOverlayView.bringToFront(); 871b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen } 872432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen updateChildIndices(); 873432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } 874432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen 87521b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen private void updateChildIndices() { 876432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen mTopViewIndex = -1; 87755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi int childCount = getChildCount(); 87855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi for (int i = 0; i < childCount; i++) { 879b670f195ffb7b4a0519fd0b337b68f7412159414Adam Cohen if (getChildAt(i) instanceof DragView) { 880432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen mTopViewIndex = i; 88155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 88221b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 8832d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen mChildCountOnLastUpdate = childCount; 88421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 88521b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen 88621b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen @Override 88721b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen protected int getChildDrawingOrder(int childCount, int i) { 8882d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen if (mChildCountOnLastUpdate != childCount) { 8892d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // between platform versions 17 and 18, behavior for onChildViewRemoved / Added changed. 8902d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // Pre-18, the child was not added / removed by the time of those callbacks. We need to 8912d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // force update our representation of things here to avoid crashing on pre-18 devices 8922d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen // in certain instances. 8932d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen updateChildIndices(); 8942d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen } 8952d783ce2f4b2e507bead0d723f0edcdf902dbd46Adam Cohen 896432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // i represents the current draw iteration 897432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen if (mTopViewIndex == -1) { 898432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // in general we do nothing 89921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 900432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } else if (i == childCount - 1) { 901432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // if we have a top index, we return it when drawing last item (highest z-order) 902432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen return mTopViewIndex; 903432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen } else if (i < mTopViewIndex) { 90421b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen return i; 90555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 906432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // for indexes greater than the top index, we fetch one item above to shift for the 907432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen // displacement of the top index 908432609a246819f3cf887a80c2ae56b61fc5ca25aAdam Cohen return i + 1; 90921b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 91021b411074e39fd10cbc8dd0220bb159da4af2c76Adam Cohen } 911360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung 912e0c332365604976d999eb25d4bdcc49ec75b7a1cTony Wickham void onEnterScrollArea() { 9130f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mInScrollArea = true; 9140f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham invalidate(); 9150f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9160f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 9170f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham void onExitScrollArea() { 9180f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mInScrollArea = false; 9190f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham invalidate(); 9200f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9210f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 9220f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham public void showPageHints() { 9230f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mShowPageHints = true; 9240f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham Workspace workspace = mLauncher.getWorkspace(); 9250f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham getDescendantRectRelativeToSelf(workspace.getChildAt(workspace.numCustomPages()), 9260f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mScrollChildPosition); 9270f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham invalidate(); 9280f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9290f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 9300f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham public void hidePageHints() { 9310f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mShowPageHints = false; 9320f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham invalidate(); 9330f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9340f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 93595cdb3a0211650e76adb451588ce89fd585b178fTony Wickham public void invalidateScrim() { 93695cdb3a0211650e76adb451588ce89fd585b178fTony Wickham if (mBackgroundAlpha > 0.0f) { 93795cdb3a0211650e76adb451588ce89fd585b178fTony Wickham invalidate(); 93895cdb3a0211650e76adb451588ce89fd585b178fTony Wickham } 93995cdb3a0211650e76adb451588ce89fd585b178fTony Wickham } 94095cdb3a0211650e76adb451588ce89fd585b178fTony Wickham 941360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung @Override 942360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung protected void dispatchDraw(Canvas canvas) { 9430fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal // Draw the background below children. 9440fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal if (mBackgroundAlpha > 0.0f) { 94595cdb3a0211650e76adb451588ce89fd585b178fTony Wickham // Update the scroll position first to ensure scrim cutout is in the right place. 94695cdb3a0211650e76adb451588ce89fd585b178fTony Wickham mLauncher.getWorkspace().computeScrollWithoutInvalidation(); 94795cdb3a0211650e76adb451588ce89fd585b178fTony Wickham 9486c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen int alpha = (int) (mBackgroundAlpha * 255); 94995cdb3a0211650e76adb451588ce89fd585b178fTony Wickham CellLayout currCellLayout = mLauncher.getWorkspace().getCurrentDragOverlappingLayout(); 95095cdb3a0211650e76adb451588ce89fd585b178fTony Wickham canvas.save(); 95195cdb3a0211650e76adb451588ce89fd585b178fTony Wickham if (currCellLayout != null && currCellLayout != mLauncher.getHotseat().getLayout()) { 95295cdb3a0211650e76adb451588ce89fd585b178fTony Wickham // Cut a hole in the darkening scrim on the page that should be highlighted, if any. 95395cdb3a0211650e76adb451588ce89fd585b178fTony Wickham getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect); 95495cdb3a0211650e76adb451588ce89fd585b178fTony Wickham canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE); 95595cdb3a0211650e76adb451588ce89fd585b178fTony Wickham } 9560fa93bc5c65a2d7d5e5f4e798499903759c48cc5Sunny Goyal canvas.drawColor((alpha << 24) | SCRIM_COLOR); 95795cdb3a0211650e76adb451588ce89fd585b178fTony Wickham canvas.restore(); 9586c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 9596c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 960360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung super.dispatchDraw(canvas); 9618cc05507150fea5282b7581e1a268967a702bcc9Adam Cohen } 962360e63fd3e77247002b86da2a77bd8dfe8c8a807Winson Chung 9630f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham private void drawPageHints(Canvas canvas) { 9640f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham if (mShowPageHints) { 9650f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham Workspace workspace = mLauncher.getWorkspace(); 9660f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham int width = getMeasuredWidth(); 9670f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham int page = workspace.getNextPage(); 9680f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham CellLayout leftPage = (CellLayout) workspace.getChildAt(mIsRtl ? page + 1 : page - 1); 9690f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham CellLayout rightPage = (CellLayout) workspace.getChildAt(mIsRtl ? page - 1 : page + 1); 9700f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 9710f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham if (leftPage != null && leftPage.isDragTarget()) { 9720f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham Drawable left = mInScrollArea && leftPage.getIsDragOverlapping() ? 9730f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mLeftHoverDrawableActive : mLeftHoverDrawable; 9740f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham left.setBounds(0, mScrollChildPosition.top, 9750f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham left.getIntrinsicWidth(), mScrollChildPosition.bottom); 9760f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham left.draw(canvas); 9770f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9780f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham if (rightPage != null && rightPage.isDragTarget()) { 9790f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham Drawable right = mInScrollArea && rightPage.getIsDragOverlapping() ? 9800f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mRightHoverDrawableActive : mRightHoverDrawable; 9810f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham right.setBounds(width - right.getIntrinsicWidth(), 9820f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham mScrollChildPosition.top, width, mScrollChildPosition.bottom); 9830f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham right.draw(canvas); 9840f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9850f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9860f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9870f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 9880f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham protected boolean drawChild(Canvas canvas, View child, long drawingTime) { 9890f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham boolean ret = super.drawChild(canvas, child, drawingTime); 9900f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 9910f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham // We want to draw the page hints above the workspace, but below the drag view. 9920f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham if (child instanceof Workspace) { 9930f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham drawPageHints(canvas); 9940f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9950f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham return ret; 9960f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham } 9970f97b7874fe29f36e7a40d2fe4b45d1e0e24fe1bTony Wickham 9986c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen public void setBackgroundAlpha(float alpha) { 9996c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen if (alpha != mBackgroundAlpha) { 10006c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen mBackgroundAlpha = alpha; 10016c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen invalidate(); 10026c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 10036c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 10046c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 10056c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen public float getBackgroundAlpha() { 10066c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen return mBackgroundAlpha; 10076c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen } 10086c5891a9fce95eee3d87823d11d21889743e9c68Adam Cohen 1009b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen public void setTouchCompleteListener(TouchCompleteListener listener) { 1010b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen mTouchCompleteListener = listener; 1011b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 1012b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen 1013b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen public interface TouchCompleteListener { 1014b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen public void onTouchComplete(); 1015b0f3d74815417acc3a9d3dce90cbf34b772847f0Adam Cohen } 101631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1017