DragLayer.java revision 8dfcba4af7a7ece09e8c7d96053e54f3a383e905
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
17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2;
1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
19716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.Animator;
20716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.AnimatorListenerAdapter;
218dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohenimport android.animation.ObjectAnimator;
22716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.TimeInterpolator;
23716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator;
24716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener;
2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context;
26716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.content.res.Resources;
27716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.graphics.Canvas;
286788269814a678af976dfc7d6135993e172ce586Adam Cohenimport android.graphics.Rect;
2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet;
3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.KeyEvent;
310e26059548e429e5d1c973bebe4c561bead2926fMichael Jurkaimport android.view.MotionEvent;
32ea3763c2672f77539538af8cdd395ad97058eaabRomain Guyimport android.view.View;
3376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.ViewParent;
34716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.view.animation.DecelerateInterpolator;
353e8f811f31a2275e778244427271f77f4116c08bAdam Cohenimport android.view.animation.Interpolator;
3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.FrameLayout;
3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
38716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport com.android.launcher.R;
39716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
401d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohenimport java.util.ArrayList;
416788269814a678af976dfc7d6135993e172ce586Adam Cohen
4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
430e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka * A ViewGroup that coordinates dragging across its descendants
4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
4500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopublic class DragLayer extends FrameLayout {
46120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen    private DragController mDragController;
47120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen    private int[] mTmpXY = new int[2];
4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
49716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    private int mXDown, mYDown;
50716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    private Launcher mLauncher;
51716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
526788269814a678af976dfc7d6135993e172ce586Adam Cohen    // Variables relating to resizing widgets
536788269814a678af976dfc7d6135993e172ce586Adam Cohen    private final ArrayList<AppWidgetResizeFrame> mResizeFrames =
546788269814a678af976dfc7d6135993e172ce586Adam Cohen            new ArrayList<AppWidgetResizeFrame>();
556788269814a678af976dfc7d6135993e172ce586Adam Cohen    private AppWidgetResizeFrame mCurrentResizeFrame;
56716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
57716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    // Variables relating to animation of views after drop
58716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    private ValueAnimator mDropAnim = null;
598dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    private ValueAnimator mFadeOutAnim = null;
608dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    private TimeInterpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f);
61716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    private View mDropView = null;
628dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen
633e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    private int[] mDropViewPos = new int[2];
643e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    private float mDropViewScale;
653e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    private float mDropViewAlpha;
666788269814a678af976dfc7d6135993e172ce586Adam Cohen
6731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Used to create a new DragLayer from XML.
6931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
7031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param context The application's context.
710e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka     * @param attrs The attributes set containing the Workspace's customization values.
7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
7331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public DragLayer(Context context, AttributeSet attrs) {
7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super(context, attrs);
75be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung
76be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung        // Disable multitouch across the workspace/all apps/customize tray
77be62afa34d58edab0fc9ba7499f0dd543039c903Winson Chung        setMotionEventSplittingEnabled(false);
7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
7931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
804c98d9235d164680186180974719f551cf935d08Winson Chung    public void setup(Launcher launcher, DragController controller) {
814c98d9235d164680186180974719f551cf935d08Winson Chung        mLauncher = launcher;
8200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragController = controller;
8331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
8476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public boolean dispatchKeyEvent(KeyEvent event) {
8700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    private boolean handleTouchDown(MotionEvent ev, boolean intercept) {
916788269814a678af976dfc7d6135993e172ce586Adam Cohen        Rect hitRect = new Rect();
926788269814a678af976dfc7d6135993e172ce586Adam Cohen        int x = (int) ev.getX();
936788269814a678af976dfc7d6135993e172ce586Adam Cohen        int y = (int) ev.getY();
946788269814a678af976dfc7d6135993e172ce586Adam Cohen
956788269814a678af976dfc7d6135993e172ce586Adam Cohen        for (AppWidgetResizeFrame child: mResizeFrames) {
966788269814a678af976dfc7d6135993e172ce586Adam Cohen            child.getHitRect(hitRect);
976788269814a678af976dfc7d6135993e172ce586Adam Cohen            if (hitRect.contains(x, y)) {
986788269814a678af976dfc7d6135993e172ce586Adam Cohen                if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
996788269814a678af976dfc7d6135993e172ce586Adam Cohen                    mCurrentResizeFrame = child;
1006788269814a678af976dfc7d6135993e172ce586Adam Cohen                    mXDown = x;
1016788269814a678af976dfc7d6135993e172ce586Adam Cohen                    mYDown = y;
1026788269814a678af976dfc7d6135993e172ce586Adam Cohen                    requestDisallowInterceptTouchEvent(true);
1036788269814a678af976dfc7d6135993e172ce586Adam Cohen                    return true;
1046788269814a678af976dfc7d6135993e172ce586Adam Cohen                }
1056788269814a678af976dfc7d6135993e172ce586Adam Cohen            }
1066788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
10776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
1081d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen        Folder currentFolder = mLauncher.getWorkspace().getOpenFolder();
1091d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen        if (currentFolder != null && intercept) {
1101d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen            if (currentFolder.isEditingName()) {
1111d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen                getDescendantRectRelativeToSelf(currentFolder.getEditTextRegion(), hitRect);
1122801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                if (!hitRect.contains(x, y)) {
1131d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen                    currentFolder.dismissEditingName();
11476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                    return true;
1152801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                }
1162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            }
11776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
1181d9af7d1e75bad13bb10ad37f5900ed59882622eAdam Cohen            getDescendantRectRelativeToSelf(currentFolder, hitRect);
11976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            if (!hitRect.contains(x, y)) {
12076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                mLauncher.closeFolder();
12176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                return true;
12276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            }
1232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
1246788269814a678af976dfc7d6135993e172ce586Adam Cohen        return false;
1256788269814a678af976dfc7d6135993e172ce586Adam Cohen    }
1266788269814a678af976dfc7d6135993e172ce586Adam Cohen
12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public boolean onInterceptTouchEvent(MotionEvent ev) {
1296788269814a678af976dfc7d6135993e172ce586Adam Cohen        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
13076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            if (handleTouchDown(ev, true)) {
1316788269814a678af976dfc7d6135993e172ce586Adam Cohen                return true;
132d1837cc69eb222371afdd30890f7215d117510f2Patrick Dubroy            }
1331b607ed454ed22c2fd855cb3e428376520fb2388Adam Cohen        }
1346788269814a678af976dfc7d6135993e172ce586Adam Cohen        clearAllResizeFrames();
1354db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato        return mDragController.onInterceptTouchEvent(ev);
13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public boolean onTouchEvent(MotionEvent ev) {
1406788269814a678af976dfc7d6135993e172ce586Adam Cohen        boolean handled = false;
1416788269814a678af976dfc7d6135993e172ce586Adam Cohen        int action = ev.getAction();
1426788269814a678af976dfc7d6135993e172ce586Adam Cohen
1436788269814a678af976dfc7d6135993e172ce586Adam Cohen        int x = (int) ev.getX();
1446788269814a678af976dfc7d6135993e172ce586Adam Cohen        int y = (int) ev.getY();
1456788269814a678af976dfc7d6135993e172ce586Adam Cohen
1466788269814a678af976dfc7d6135993e172ce586Adam Cohen        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
1476788269814a678af976dfc7d6135993e172ce586Adam Cohen            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
14876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                if (handleTouchDown(ev, false)) {
1496788269814a678af976dfc7d6135993e172ce586Adam Cohen                    return true;
1506788269814a678af976dfc7d6135993e172ce586Adam Cohen                }
1516788269814a678af976dfc7d6135993e172ce586Adam Cohen            }
1526788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
1536788269814a678af976dfc7d6135993e172ce586Adam Cohen
1546788269814a678af976dfc7d6135993e172ce586Adam Cohen        if (mCurrentResizeFrame != null) {
1556788269814a678af976dfc7d6135993e172ce586Adam Cohen            handled = true;
1566788269814a678af976dfc7d6135993e172ce586Adam Cohen            switch (action) {
1576788269814a678af976dfc7d6135993e172ce586Adam Cohen                case MotionEvent.ACTION_MOVE:
1586788269814a678af976dfc7d6135993e172ce586Adam Cohen                    mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown);
1596788269814a678af976dfc7d6135993e172ce586Adam Cohen                    break;
1606788269814a678af976dfc7d6135993e172ce586Adam Cohen                case MotionEvent.ACTION_CANCEL:
1616788269814a678af976dfc7d6135993e172ce586Adam Cohen                case MotionEvent.ACTION_UP:
1626788269814a678af976dfc7d6135993e172ce586Adam Cohen                    mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown);
1636788269814a678af976dfc7d6135993e172ce586Adam Cohen                    mCurrentResizeFrame = null;
1646788269814a678af976dfc7d6135993e172ce586Adam Cohen            }
1656788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
1666788269814a678af976dfc7d6135993e172ce586Adam Cohen        if (handled) return true;
1674db52312c10e822162a21c60404f06f6e507f0d6Joe Onorato        return mDragController.onTouchEvent(ev);
16891a9c9636f10f1e12cd1f660b2e330634fbdc7dcRomain Guy    }
169ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy
1708e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen    public void getDescendantRectRelativeToSelf(View descendant, Rect r) {
171716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        mTmpXY[0] = 0;
172716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        mTmpXY[1] = 0;
173716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        getDescendantCoordRelativeToSelf(descendant, mTmpXY);
1748dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        r.set(mTmpXY[0], mTmpXY[1],
1758dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                mTmpXY[0] + descendant.getWidth(), mTmpXY[1] + descendant.getHeight());
176716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    }
17776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
1788dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    private void getDescendantCoordRelativeToSelf(View descendant, int[] coord) {
1798dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        coord[0] += descendant.getLeft();
1808dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        coord[1] += descendant.getTop();
18176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        ViewParent viewParent = descendant.getParent();
18276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        while (viewParent instanceof View && viewParent != this) {
18376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            final View view = (View)viewParent;
184716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            coord[0] += view.getLeft() + (int) (view.getTranslationX() + 0.5f) - view.getScrollX();
185716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            coord[1] += view.getTop() + (int) (view.getTranslationY() + 0.5f) - view.getScrollY();
18676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            viewParent = view.getParent();
18776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        }
18876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
18976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
1908dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    public void getLocationInDragLayer(View child, int[] loc) {
1918dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        loc[0] = 0;
1928dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        loc[1] = 0;
1938dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        getDescendantCoordRelativeToSelf(child, loc);
1948dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    }
1958dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen
1963e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    public void getViewRectRelativeToSelf(View v, Rect r) {
1973e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        int[] loc = new int[2];
1988dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        getLocationInWindow(loc);
1993e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        int x = loc[0];
2003e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        int y = loc[1];
201716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
2028dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        v.getLocationInWindow(loc);
2033e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        int vX = loc[0];
2043e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        int vY = loc[1];
205716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
2063e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        int left = vX - x;
2073e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        int top = vY - y;
2083e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        r.set(left, top, left + v.getMeasuredWidth(), top + v.getMeasuredHeight());
209716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    }
210716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
211ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    @Override
212ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    public boolean dispatchUnhandledMove(View focused, int direction) {
213ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy        return mDragController.dispatchUnhandledMove(focused, direction);
214ea3763c2672f77539538af8cdd395ad97058eaabRomain Guy    }
215120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen
2166788269814a678af976dfc7d6135993e172ce586Adam Cohen    public static class LayoutParams extends FrameLayout.LayoutParams {
2176788269814a678af976dfc7d6135993e172ce586Adam Cohen        public int x, y;
2186788269814a678af976dfc7d6135993e172ce586Adam Cohen        public boolean customPosition = false;
2196788269814a678af976dfc7d6135993e172ce586Adam Cohen
2206788269814a678af976dfc7d6135993e172ce586Adam Cohen        /**
2216788269814a678af976dfc7d6135993e172ce586Adam Cohen         * {@inheritDoc}
2226788269814a678af976dfc7d6135993e172ce586Adam Cohen         */
2236788269814a678af976dfc7d6135993e172ce586Adam Cohen        public LayoutParams(int width, int height) {
2246788269814a678af976dfc7d6135993e172ce586Adam Cohen            super(width, height);
2256788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2266788269814a678af976dfc7d6135993e172ce586Adam Cohen
2276788269814a678af976dfc7d6135993e172ce586Adam Cohen        public void setWidth(int width) {
2286788269814a678af976dfc7d6135993e172ce586Adam Cohen            this.width = width;
2296788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2306788269814a678af976dfc7d6135993e172ce586Adam Cohen
2316788269814a678af976dfc7d6135993e172ce586Adam Cohen        public int getWidth() {
2326788269814a678af976dfc7d6135993e172ce586Adam Cohen            return width;
2336788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2346788269814a678af976dfc7d6135993e172ce586Adam Cohen
2356788269814a678af976dfc7d6135993e172ce586Adam Cohen        public void setHeight(int height) {
2366788269814a678af976dfc7d6135993e172ce586Adam Cohen            this.height = height;
2376788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2386788269814a678af976dfc7d6135993e172ce586Adam Cohen
2396788269814a678af976dfc7d6135993e172ce586Adam Cohen        public int getHeight() {
2406788269814a678af976dfc7d6135993e172ce586Adam Cohen            return height;
2416788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2426788269814a678af976dfc7d6135993e172ce586Adam Cohen
2436788269814a678af976dfc7d6135993e172ce586Adam Cohen        public void setX(int x) {
2446788269814a678af976dfc7d6135993e172ce586Adam Cohen            this.x = x;
2456788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2466788269814a678af976dfc7d6135993e172ce586Adam Cohen
2476788269814a678af976dfc7d6135993e172ce586Adam Cohen        public int getX() {
2486788269814a678af976dfc7d6135993e172ce586Adam Cohen            return x;
2496788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2506788269814a678af976dfc7d6135993e172ce586Adam Cohen
2516788269814a678af976dfc7d6135993e172ce586Adam Cohen        public void setY(int y) {
2526788269814a678af976dfc7d6135993e172ce586Adam Cohen            this.y = y;
2536788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2546788269814a678af976dfc7d6135993e172ce586Adam Cohen
2556788269814a678af976dfc7d6135993e172ce586Adam Cohen        public int getY() {
2566788269814a678af976dfc7d6135993e172ce586Adam Cohen            return y;
2576788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2586788269814a678af976dfc7d6135993e172ce586Adam Cohen    }
2596788269814a678af976dfc7d6135993e172ce586Adam Cohen
2606788269814a678af976dfc7d6135993e172ce586Adam Cohen    protected void onLayout(boolean changed, int l, int t, int r, int b) {
2616788269814a678af976dfc7d6135993e172ce586Adam Cohen        super.onLayout(changed, l, t, r, b);
2626788269814a678af976dfc7d6135993e172ce586Adam Cohen        int count = getChildCount();
2636788269814a678af976dfc7d6135993e172ce586Adam Cohen        for (int i = 0; i < count; i++) {
2646788269814a678af976dfc7d6135993e172ce586Adam Cohen            View child = getChildAt(i);
2656788269814a678af976dfc7d6135993e172ce586Adam Cohen            final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
2666788269814a678af976dfc7d6135993e172ce586Adam Cohen            if (flp instanceof LayoutParams) {
2676788269814a678af976dfc7d6135993e172ce586Adam Cohen                final LayoutParams lp = (LayoutParams) flp;
2686788269814a678af976dfc7d6135993e172ce586Adam Cohen                if (lp.customPosition) {
2696788269814a678af976dfc7d6135993e172ce586Adam Cohen                    child.layout(lp.x, lp.y, lp.x + lp.width, lp.y + lp.height);
2706788269814a678af976dfc7d6135993e172ce586Adam Cohen                }
2716788269814a678af976dfc7d6135993e172ce586Adam Cohen            }
2726788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2736788269814a678af976dfc7d6135993e172ce586Adam Cohen    }
2746788269814a678af976dfc7d6135993e172ce586Adam Cohen
2756788269814a678af976dfc7d6135993e172ce586Adam Cohen    public void clearAllResizeFrames() {
2766788269814a678af976dfc7d6135993e172ce586Adam Cohen        if (mResizeFrames.size() > 0) {
2776788269814a678af976dfc7d6135993e172ce586Adam Cohen            for (AppWidgetResizeFrame frame: mResizeFrames) {
2786788269814a678af976dfc7d6135993e172ce586Adam Cohen                removeView(frame);
2796788269814a678af976dfc7d6135993e172ce586Adam Cohen            }
2806788269814a678af976dfc7d6135993e172ce586Adam Cohen            mResizeFrames.clear();
2816788269814a678af976dfc7d6135993e172ce586Adam Cohen        }
2826788269814a678af976dfc7d6135993e172ce586Adam Cohen    }
2836788269814a678af976dfc7d6135993e172ce586Adam Cohen
2846788269814a678af976dfc7d6135993e172ce586Adam Cohen    public boolean hasResizeFrames() {
2856788269814a678af976dfc7d6135993e172ce586Adam Cohen        return mResizeFrames.size() > 0;
2866788269814a678af976dfc7d6135993e172ce586Adam Cohen    }
2876788269814a678af976dfc7d6135993e172ce586Adam Cohen
2886788269814a678af976dfc7d6135993e172ce586Adam Cohen    public boolean isWidgetBeingResized() {
2896788269814a678af976dfc7d6135993e172ce586Adam Cohen        return mCurrentResizeFrame != null;
2906788269814a678af976dfc7d6135993e172ce586Adam Cohen    }
2916788269814a678af976dfc7d6135993e172ce586Adam Cohen
2926788269814a678af976dfc7d6135993e172ce586Adam Cohen    public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget,
2936788269814a678af976dfc7d6135993e172ce586Adam Cohen            CellLayout cellLayout) {
2946788269814a678af976dfc7d6135993e172ce586Adam Cohen        AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(),
2956788269814a678af976dfc7d6135993e172ce586Adam Cohen                itemInfo, widget, cellLayout, this);
2966788269814a678af976dfc7d6135993e172ce586Adam Cohen
2976788269814a678af976dfc7d6135993e172ce586Adam Cohen        LayoutParams lp = new LayoutParams(-1, -1);
2986788269814a678af976dfc7d6135993e172ce586Adam Cohen        lp.customPosition = true;
2996788269814a678af976dfc7d6135993e172ce586Adam Cohen
3006788269814a678af976dfc7d6135993e172ce586Adam Cohen        addView(resizeFrame, lp);
3016788269814a678af976dfc7d6135993e172ce586Adam Cohen        mResizeFrames.add(resizeFrame);
3026788269814a678af976dfc7d6135993e172ce586Adam Cohen
3036788269814a678af976dfc7d6135993e172ce586Adam Cohen        resizeFrame.snapToWidget(false);
3046788269814a678af976dfc7d6135993e172ce586Adam Cohen    }
305716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
306716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    public void animateViewIntoPosition(DragView dragView, final View child) {
307716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        ((CellLayoutChildren) child.getParent()).measureChild(child);
308716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        CellLayout.LayoutParams lp =  (CellLayout.LayoutParams) child.getLayoutParams();
309716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
3103e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        Rect r = new Rect();
3113e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        getViewRectRelativeToSelf(dragView, r);
312716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
313716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        int coord[] = new int[2];
314716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        coord[0] = lp.x;
315716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        coord[1] = lp.y;
3168dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        // Since the child hasn't necessarily been laid out, we force the lp to be updated with
3178dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        // the correct coordinates and use these to determine the final location
3188dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        getDescendantCoordRelativeToSelf((View) child.getParent(), coord);
3198dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        int toX = coord[0] - (dragView.getWidth() - child.getMeasuredWidth()) / 2;
3208dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        int toY = coord[1] - (dragView.getHeight() - child.getMeasuredHeight()) / 2;
321716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
3223e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        final int fromX = r.left + (dragView.getWidth() - child.getMeasuredWidth())  / 2;
3233e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        final int fromY = r.top + (dragView.getHeight() - child.getMeasuredHeight())  / 2;
324716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        child.setVisibility(INVISIBLE);
3258dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        child.setAlpha(0);
3268dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        Runnable onCompleteRunnable = new Runnable() {
3278dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            public void run() {
3288dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                child.setVisibility(VISIBLE);
3298dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                ObjectAnimator oa = ObjectAnimator.ofFloat(child, "alpha", 0f, 1f);
3308dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                oa.setDuration(60);
3318dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                oa.start();
3328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            }
3338dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        };
3348dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        animateViewIntoPosition(dragView, fromX, fromY, toX, toY, onCompleteRunnable, true);
335716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    }
336716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
337716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    private void animateViewIntoPosition(final View view, final int fromX, final int fromY,
3388dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            final int toX, final int toY, Runnable onCompleteRunnable, boolean fadeOut) {
3398dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        Rect from = new Rect(fromX, fromY, fromX +
3408dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                view.getMeasuredWidth(), fromY + view.getMeasuredHeight());
3413e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        Rect to = new Rect(toX, toY, toX + view.getMeasuredWidth(), toY + view.getMeasuredHeight());
3428dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        animateView(view, from, to, 1f, 1.0f, -1, null, null, onCompleteRunnable, true);
343716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
3443e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    }
3453e8f811f31a2275e778244427271f77f4116c08bAdam Cohen
3463e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    public void animateView(final View view, final Rect from, final Rect to, final float finalAlpha,
3473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            final float finalScale, int duration, final Interpolator motionInterpolator,
3488dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            final Interpolator alphaInterpolator, final Runnable onCompleteRunnable,
3498dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            final boolean fadeOut) {
350716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        // Calculate the duration of the animation based on the object's distance
3513e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        final float dist = (float) Math.sqrt(Math.pow(to.left - from.left, 2) +
3523e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                Math.pow(to.top - from.top, 2));
353716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        final Resources res = getResources();
354716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist);
3553e8f811f31a2275e778244427271f77f4116c08bAdam Cohen
3563e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        // If duration < 0, this is a cue to compute the duration based on the distance
3573e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        if (duration < 0) {
3583e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            duration = res.getInteger(R.integer.config_dropAnimMaxDuration);
3593e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            if (dist < maxDist) {
3608dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist);
3613e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            }
362716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        }
363716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
364716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        if (mDropAnim != null) {
3658dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            mDropAnim.cancel();
366716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        }
367716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
3683e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        mDropView = view;
3693e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        final float initialAlpha = view.getAlpha();
3703e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        mDropAnim = new ValueAnimator();
3713e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        if (alphaInterpolator == null || motionInterpolator == null) {
3728dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            mDropAnim.setInterpolator(mCubicEaseOutInterpolator);
3733e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        }
374716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
375716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        mDropAnim.setDuration(duration);
376716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        mDropAnim.setFloatValues(0.0f, 1.0f);
377716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        mDropAnim.removeAllUpdateListeners();
378716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        mDropAnim.addUpdateListener(new AnimatorUpdateListener() {
379716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            public void onAnimationUpdate(ValueAnimator animation) {
380716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                final float percent = (Float) animation.getAnimatedValue();
381716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                // Invalidate the old position
382716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                int width = view.getMeasuredWidth();
383716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                int height = view.getMeasuredHeight();
384716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                invalidate(mDropViewPos[0], mDropViewPos[1],
385716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                        mDropViewPos[0] + width, mDropViewPos[1] + height);
386716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
3873e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                float alphaPercent = alphaInterpolator == null ? percent :
3883e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                        alphaInterpolator.getInterpolation(percent);
3893e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                float motionPercent = motionInterpolator == null ? percent :
3903e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                        motionInterpolator.getInterpolation(percent);
3913e8f811f31a2275e778244427271f77f4116c08bAdam Cohen
3923e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                mDropViewPos[0] = from.left + (int) ((to.left - from.left) * motionPercent);
3933e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                mDropViewPos[1] = from.top + (int) ((to.top - from.top) * motionPercent);
3943e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                mDropViewScale = percent * finalScale + (1 - percent);
3953e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                mDropViewAlpha = alphaPercent * finalAlpha + (1 - alphaPercent) * initialAlpha;
396716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                invalidate(mDropViewPos[0], mDropViewPos[1],
397716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen                        mDropViewPos[0] + width, mDropViewPos[1] + height);
398716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            }
399716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        });
4003e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        mDropAnim.addListener(new AnimatorListenerAdapter() {
4013e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            public void onAnimationEnd(Animator animation) {
4028dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                if (onCompleteRunnable != null) {
4038dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                    onCompleteRunnable.run();
4048dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                }
4058dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                if (fadeOut) {
4068dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                    fadeOutDragView();
4078dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                } else {
4083e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                    mDropView = null;
4093e8f811f31a2275e778244427271f77f4116c08bAdam Cohen                }
4103e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            }
4113e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        });
412716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        mDropAnim.start();
413716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    }
414716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
4158dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    private void fadeOutDragView() {
4168dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mFadeOutAnim = new ValueAnimator();
4178dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mFadeOutAnim.setDuration(150);
4188dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mFadeOutAnim.setFloatValues(0f, 1f);
4198dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mFadeOutAnim.removeAllUpdateListeners();
4208dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mFadeOutAnim.addUpdateListener(new AnimatorUpdateListener() {
4218dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            public void onAnimationUpdate(ValueAnimator animation) {
4228dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                final float percent = (Float) animation.getAnimatedValue();
4238dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                mDropViewAlpha = 1 - percent;
4248dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                int width = mDropView.getMeasuredWidth();
4258dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                int height = mDropView.getMeasuredHeight();
4268dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                invalidate(mDropViewPos[0], mDropViewPos[1],
4278dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                        mDropViewPos[0] + width, mDropViewPos[1] + height);
4288dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            }
4298dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        });
4308dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mFadeOutAnim.addListener(new AnimatorListenerAdapter() {
4318dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            public void onAnimationEnd(Animator animation) {
4328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen                mDropView = null;
4338dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen            }
4348dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        });
4358dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mFadeOutAnim.start();
4368dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    }
4378dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen
438716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    @Override
439716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    protected void dispatchDraw(Canvas canvas) {
440716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        super.dispatchDraw(canvas);
441716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        if (mDropView != null) {
442716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            // We are animating an item that was just dropped on the home screen.
443716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            // Render its View in the current animation position.
444716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            canvas.save(Canvas.MATRIX_SAVE_FLAG);
445716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            final int xPos = mDropViewPos[0] - mDropView.getScrollX();
446716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            final int yPos = mDropViewPos[1] - mDropView.getScrollY();
4473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            int width = mDropView.getMeasuredWidth();
4483e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            int height = mDropView.getMeasuredHeight();
449716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            canvas.translate(xPos, yPos);
4503e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            canvas.translate((1 - mDropViewScale) * width / 2, (1 - mDropViewScale) * height / 2);
4513e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            canvas.scale(mDropViewScale, mDropViewScale);
4523e8f811f31a2275e778244427271f77f4116c08bAdam Cohen            mDropView.setAlpha(mDropViewAlpha);
453716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            mDropView.draw(canvas);
454716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen            canvas.restore();
455716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen        }
456716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen    }
45731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
458