DragView.java revision 091440a9cb9d4f42406631004aa484cbb79214ca
100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato/*
200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Copyright (C) 2008 The Android Open Source Project
300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato *
400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * you may not use this file except in compliance with the License.
600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * You may obtain a copy of the License at
700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato *
800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato *
1000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * Unless required by applicable law or agreed to in writing, software
1100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
1200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * See the License for the specific language governing permissions and
1400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato * limitations under the License.
1500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */
1600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3;
1800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
19a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.animation.ValueAnimator;
20a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.animation.ValueAnimator.AnimatorUpdateListener;
21de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroyimport android.content.res.Resources;
2200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap;
2300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Canvas;
2400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Paint;
25b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chungimport android.graphics.Point;
2661967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chungimport android.graphics.PorterDuff;
2761967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chungimport android.graphics.PorterDuffColorFilter;
28e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohenimport android.graphics.Rect;
2900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.View;
30a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.view.animation.DecelerateInterpolator;
3100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
32091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk;
33091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen
34a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroypublic class DragView extends View {
35091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk static float sDragAlpha = 1f;
367bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
3700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Bitmap mBitmap;
38ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    private Bitmap mCrossFadeBitmap;
3900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Paint mPaint;
4000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mRegistrationX;
4100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mRegistrationY;
4200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
43b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    private Point mDragVisualizeOffset = null;
44e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    private Rect mDragRegion = null;
458dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    private DragLayer mDragLayer = null;
46fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    private boolean mHasDrawn = false;
47091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk float mCrossFadeProgress = 0f;
48a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
49a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    ValueAnimator mAnim;
50091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk float mOffsetX = 0.0f;
51091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen    @Thunk float mOffsetY = 0.0f;
52043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    private float mInitialScale = 1f;
53eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    // The intrinsic icon scale factor is the scale factor for a drag icon over the workspace
54eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    // size.  This is ignored for non-icons.
55eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    private float mIntrinsicIconScale = 1f;
5600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
5800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Construct the drag view.
5900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * <p>
6000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * The registration point is the point inside our view that the touch events should
6100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * be centered upon.
6200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
638dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param launcher The Launcher instance
6400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param bitmap The view that we're dragging around.  We scale it up when we draw it.
6500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param registrationX The x coordinate of the registration point.
6600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param registrationY The y coordinate of the registration point.
6700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY,
6972d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung            int left, int top, int width, int height, final float initialScale) {
708dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        super(launcher);
718dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mDragLayer = launcher.getDragLayer();
72043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        mInitialScale = initialScale;
7300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
74de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        final Resources res = getResources();
757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float scaleDps = res.getDimensionPixelSize(R.dimen.dragViewScale);
767bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float scale = (width + scaleDps) / width;
77a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
78307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen        // Set the initial scale to avoid any jumps
79307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen        setScaleX(initialScale);
80307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen        setScaleY(initialScale);
81307fe23f125cbbd5512ad8d4660025f2ab68f30bAdam Cohen
82a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        // Animate the view into the correct position
83f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        mAnim = LauncherAnimUtils.ofFloat(this, 0f, 1f);
847bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        mAnim.setDuration(150);
85a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mAnim.addUpdateListener(new AnimatorUpdateListener() {
86a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy            @Override
87a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy            public void onAnimationUpdate(ValueAnimator animation) {
88a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                final float value = (Float) animation.getAnimatedValue();
89a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
90560616da70648bed04c00aa804503ec72ace1337Sunny Goyal                final int deltaX = (int) (-mOffsetX);
91560616da70648bed04c00aa804503ec72ace1337Sunny Goyal                final int deltaY = (int) (-mOffsetY);
92a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
93a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                mOffsetX += deltaX;
94a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                mOffsetY += deltaY;
9572d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung                setScaleX(initialScale + (value * (scale - initialScale)));
9672d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung                setScaleY(initialScale + (value * (scale - initialScale)));
97867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung                if (sDragAlpha != 1f) {
98867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung                    setAlpha(sDragAlpha * value + (1f - value));
99867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung                }
100a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
101a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                if (getParent() == null) {
102a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                    animation.cancel();
103a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                } else {
1047bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung                    setTranslationX(getTranslationX() + deltaX);
1057bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung                    setTranslationY(getTranslationY() + deltaY);
106a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                }
107a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy            }
108a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        });
10900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
1107bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height);
111e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        setDragRegion(new Rect(0, 0, width, height));
11200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
11300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // The point in our scaled bitmap that the touch events are located
114a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mRegistrationX = registrationX;
115a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mRegistrationY = registrationY;
11662bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy
11762bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass
11862bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
11962bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        measure(ms, ms);
1206cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
12162bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy    }
12262bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy
123eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    /** Sets the scale of the view over the normal workspace icon size. */
124eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    public void setIntrinsicIconScaleFactor(float scale) {
125eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung        mIntrinsicIconScale = scale;
126eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    }
127eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung
128eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    public float getIntrinsicIconScaleFactor() {
129eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung        return mIntrinsicIconScale;
130eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung    }
131eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung
13262bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy    public float getOffsetY() {
13362bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        return mOffsetY;
13400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
13500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
136a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionLeft() {
137e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.left;
138a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
139a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
140a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionTop() {
141e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.top;
142a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
143a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
144a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionWidth() {
145e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.width();
146a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
147a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
148a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionHeight() {
149e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.height();
150e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    }
151e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen
152b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    public void setDragVisualizeOffset(Point p) {
153b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        mDragVisualizeOffset = p;
154b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    }
155b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung
156b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    public Point getDragVisualizeOffset() {
157b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        return mDragVisualizeOffset;
158b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    }
159b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung
160e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    public void setDragRegion(Rect r) {
161e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        mDragRegion = r;
162e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    }
163e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen
164e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    public Rect getDragRegion() {
165e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion;
166a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
167a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
168043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    public float getInitialScale() {
169043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        return mInitialScale;
170043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    }
171043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
172043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    public void updateInitialScaleToCurrentScale() {
173043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        mInitialScale = getScaleX();
174043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    }
175043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
17600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    @Override
17700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
178eebd92496e2fbfbd81ea871862a681929101ba06Joe Onorato        setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
17900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
18000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
18100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    @Override
18200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected void onDraw(Canvas canvas) {
1833a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka        @SuppressWarnings("all") // suppress dead code warning
1843a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka        final boolean debug = false;
1853a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka        if (debug) {
18600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            Paint p = new Paint();
18700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            p.setStyle(Paint.Style.FILL);
188eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung            p.setColor(0x66ffffff);
18900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            canvas.drawRect(0, 0, getWidth(), getHeight(), p);
19000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
191a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
192fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen        mHasDrawn = true;
193ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null;
194ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        if (crossFade) {
195ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255;
196ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            mPaint.setAlpha(alpha);
197ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        }
19800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
199ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        if (crossFade) {
200ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            mPaint.setAlpha((int) (255 * mCrossFadeProgress));
201ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.save();
202ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth();
203ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight();
204ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.scale(sX, sY);
205ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint);
206ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.restore();
207ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        }
208ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    }
209ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen
210ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    public void setCrossFadeBitmap(Bitmap crossFadeBitmap) {
211ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        mCrossFadeBitmap = crossFadeBitmap;
212ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    }
213ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen
214ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    public void crossFade(int duration) {
215f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        ValueAnimator va = LauncherAnimUtils.ofFloat(this, 0f, 1f);
216ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.setDuration(duration);
217ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.setInterpolator(new DecelerateInterpolator(1.5f));
218ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.addUpdateListener(new AnimatorUpdateListener() {
219ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            @Override
220ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            public void onAnimationUpdate(ValueAnimator animation) {
221ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen                mCrossFadeProgress = animation.getAnimatedFraction();
222ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            }
223ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        });
224ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.start();
22500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
22600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
22761967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung    public void setColor(int color) {
2286cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        if (mPaint == null) {
2296cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka            mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
2306cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        }
23161967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        if (color != 0) {
23261967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung            mPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
23361967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        } else {
23461967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung            mPaint.setColorFilter(null);
23561967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        }
23600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        invalidate();
23700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
23800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
239fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    public boolean hasDrawn() {
240fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen        return mHasDrawn;
241fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    }
242fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen
2433e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    @Override
2443e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    public void setAlpha(float alpha) {
2453e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        super.setAlpha(alpha);
2463e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        mPaint.setAlpha((int) (255 * alpha));
2473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        invalidate();
2483e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    }
2493e8f811f31a2275e778244427271f77f4116c08bAdam Cohen
25000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
25100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Create a window containing this view and show it.
25200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
25300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param windowToken obtained from v.getWindowToken() from one of your views
2548dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchX the x coordinate the user touched in DragLayer coordinates
2558dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchY the y coordinate the user touched in DragLayer coordinates
25600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
2578dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    public void show(int touchX, int touchY) {
2588dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mDragLayer.addView(this);
259043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
260043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        // Start the pick-up animation
2618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0);
2628dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.width = mBitmap.getWidth();
2638dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.height = mBitmap.getHeight();
2648dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.customPosition = true;
2658dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        setLayoutParams(lp);
2667bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationX(touchX - mRegistrationX);
2677bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationY(touchY - mRegistrationY);
268ca99383daef92fed673de22126875cb485be494fMichael Jurka        // Post the animation to skip other expensive work happening on the first frame
269ca99383daef92fed673de22126875cb485be494fMichael Jurka        post(new Runnable() {
270ca99383daef92fed673de22126875cb485be494fMichael Jurka                public void run() {
271ca99383daef92fed673de22126875cb485be494fMichael Jurka                    mAnim.start();
272ca99383daef92fed673de22126875cb485be494fMichael Jurka                }
273ca99383daef92fed673de22126875cb485be494fMichael Jurka            });
27400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
275716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
2767bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    public void cancelAnimation() {
2777bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        if (mAnim != null && mAnim.isRunning()) {
2787bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung            mAnim.cancel();
2797bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        }
2807bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    }
2817bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
2827bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    public void resetLayoutParams() {
2837bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        mOffsetX = mOffsetY = 0;
2847bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        requestLayout();
2857bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    }
2867bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
28700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
28800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Move the window containing this view.
28900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
2908dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchX the x coordinate the user touched in DragLayer coordinates
2918dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchY the y coordinate the user touched in DragLayer coordinates
29200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
29300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void move(int touchX, int touchY) {
2947bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationX(touchX - mRegistrationX + (int) mOffsetX);
2957bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationY(touchY - mRegistrationY + (int) mOffsetY);
29600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
29700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
29800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void remove() {
2997bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        if (getParent() != null) {
3007bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung            mDragLayer.removeView(DragView.this);
3017bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        }
3026f13342ffd3f968de9ff86b988621cc91d94adffPatrick Dubroy    }
30300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato}
30400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
305