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
1700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
1800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratopackage com.android.launcher2;
1900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
20a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.animation.ValueAnimator;
21a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.animation.ValueAnimator.AnimatorUpdateListener;
22de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroyimport android.content.res.Resources;
2300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Bitmap;
2400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Canvas;
2500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Paint;
26b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chungimport android.graphics.Point;
2761967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chungimport android.graphics.PorterDuff;
2861967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chungimport android.graphics.PorterDuffColorFilter;
29e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohenimport android.graphics.Rect;
3000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.View;
31a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.view.animation.DecelerateInterpolator;
3200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
33120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohenimport com.android.launcher.R;
34120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen
35a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroypublic class DragView extends View {
36867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung    private static float sDragAlpha = 1f;
377bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
3800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Bitmap mBitmap;
39ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    private Bitmap mCrossFadeBitmap;
4000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Paint mPaint;
4100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mRegistrationX;
4200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mRegistrationY;
4300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
44b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    private Point mDragVisualizeOffset = null;
45e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    private Rect mDragRegion = null;
468dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    private DragLayer mDragLayer = null;
47fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    private boolean mHasDrawn = false;
48ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    private float mCrossFadeProgress = 0f;
49a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
50a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    ValueAnimator mAnim;
51a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    private float mOffsetX = 0.0f;
52a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    private float mOffsetY = 0.0f;
53043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    private float mInitialScale = 1f;
5400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
5500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
5600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Construct the drag view.
5700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * <p>
5800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * The registration point is the point inside our view that the touch events should
5900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * be centered upon.
6000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param launcher The Launcher instance
6200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param bitmap The view that we're dragging around.  We scale it up when we draw it.
6300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param registrationX The x coordinate of the registration point.
6400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param registrationY The y coordinate of the registration point.
6500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
668dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    public DragView(Launcher launcher, Bitmap bitmap, int registrationX, int registrationY,
6772d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung            int left, int top, int width, int height, final float initialScale) {
688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        super(launcher);
698dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mDragLayer = launcher.getDragLayer();
70043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        mInitialScale = initialScale;
7100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
72de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        final Resources res = getResources();
737bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX);
747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY);
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
90a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                final int deltaX = (int) ((value * offsetX) - mOffsetX);
91a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                final int deltaY = (int) ((value * offsetY) - 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
12362bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy    public float getOffsetY() {
12462bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        return mOffsetY;
12500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
12600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
127a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionLeft() {
128e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.left;
129a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
130a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
131a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionTop() {
132e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.top;
133a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
134a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
135a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionWidth() {
136e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.width();
137a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
138a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
139a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionHeight() {
140e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.height();
141e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    }
142e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen
143b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    public void setDragVisualizeOffset(Point p) {
144b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        mDragVisualizeOffset = p;
145b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    }
146b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung
147b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    public Point getDragVisualizeOffset() {
148b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        return mDragVisualizeOffset;
149b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    }
150b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung
151e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    public void setDragRegion(Rect r) {
152e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        mDragRegion = r;
153e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    }
154e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen
155e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    public Rect getDragRegion() {
156e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion;
157a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
158a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
159043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    public float getInitialScale() {
160043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        return mInitialScale;
161043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    }
162043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
163043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    public void updateInitialScaleToCurrentScale() {
164043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        mInitialScale = getScaleX();
165043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung    }
166043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
16700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    @Override
16800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
169eebd92496e2fbfbd81ea871862a681929101ba06Joe Onorato        setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
17000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
17100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
17200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    @Override
17300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected void onDraw(Canvas canvas) {
1743a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka        @SuppressWarnings("all") // suppress dead code warning
1753a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka        final boolean debug = false;
1763a9fcedbcd235372cd2ab64f825a0b5b3937f59eMichael Jurka        if (debug) {
17700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            Paint p = new Paint();
17800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            p.setStyle(Paint.Style.FILL);
179eecf02da58adef5486bf0c9ff7127ea891f457a4Winson Chung            p.setColor(0x66ffffff);
18000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            canvas.drawRect(0, 0, getWidth(), getHeight(), p);
18100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
182a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
183fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen        mHasDrawn = true;
184ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null;
185ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        if (crossFade) {
186ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255;
187ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            mPaint.setAlpha(alpha);
188ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        }
18900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
190ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        if (crossFade) {
191ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            mPaint.setAlpha((int) (255 * mCrossFadeProgress));
192ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.save();
193ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth();
194ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight();
195ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.scale(sX, sY);
196ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint);
197ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.restore();
198ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        }
199ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    }
200ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen
201ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    public void setCrossFadeBitmap(Bitmap crossFadeBitmap) {
202ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        mCrossFadeBitmap = crossFadeBitmap;
203ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    }
204ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen
205ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    public void crossFade(int duration) {
206f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        ValueAnimator va = LauncherAnimUtils.ofFloat(this, 0f, 1f);
207ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.setDuration(duration);
208ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.setInterpolator(new DecelerateInterpolator(1.5f));
209ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.addUpdateListener(new AnimatorUpdateListener() {
210ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            @Override
211ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            public void onAnimationUpdate(ValueAnimator animation) {
212ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen                mCrossFadeProgress = animation.getAnimatedFraction();
213ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            }
214ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        });
215ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.start();
21600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
21700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
21861967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung    public void setColor(int color) {
2196cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        if (mPaint == null) {
2206cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka            mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
2216cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        }
22261967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        if (color != 0) {
22361967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung            mPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
22461967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        } else {
22561967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung            mPaint.setColorFilter(null);
22661967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        }
22700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        invalidate();
22800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
22900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
230fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    public boolean hasDrawn() {
231fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen        return mHasDrawn;
232fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    }
233fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen
2343e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    @Override
2353e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    public void setAlpha(float alpha) {
2363e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        super.setAlpha(alpha);
2373e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        mPaint.setAlpha((int) (255 * alpha));
2383e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        invalidate();
2393e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    }
2403e8f811f31a2275e778244427271f77f4116c08bAdam Cohen
24100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
24200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Create a window containing this view and show it.
24300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
24400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param windowToken obtained from v.getWindowToken() from one of your views
2458dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchX the x coordinate the user touched in DragLayer coordinates
2468dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchY the y coordinate the user touched in DragLayer coordinates
24700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
2488dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    public void show(int touchX, int touchY) {
2498dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mDragLayer.addView(this);
250043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung
251043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung        // Start the pick-up animation
2528dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0);
2538dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.width = mBitmap.getWidth();
2548dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.height = mBitmap.getHeight();
2558dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.customPosition = true;
2568dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        setLayoutParams(lp);
2577bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationX(touchX - mRegistrationX);
2587bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationY(touchY - mRegistrationY);
259ca99383daef92fed673de22126875cb485be494fMichael Jurka        // Post the animation to skip other expensive work happening on the first frame
260ca99383daef92fed673de22126875cb485be494fMichael Jurka        post(new Runnable() {
261ca99383daef92fed673de22126875cb485be494fMichael Jurka                public void run() {
262ca99383daef92fed673de22126875cb485be494fMichael Jurka                    mAnim.start();
263ca99383daef92fed673de22126875cb485be494fMichael Jurka                }
264ca99383daef92fed673de22126875cb485be494fMichael Jurka            });
26500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
266716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
2677bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    public void cancelAnimation() {
2687bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        if (mAnim != null && mAnim.isRunning()) {
2697bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung            mAnim.cancel();
2707bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        }
2717bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    }
2727bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
2737bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    public void resetLayoutParams() {
2747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        mOffsetX = mOffsetY = 0;
2757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        requestLayout();
2767bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    }
2777bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
27800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
27900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Move the window containing this view.
28000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
2818dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchX the x coordinate the user touched in DragLayer coordinates
2828dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchY the y coordinate the user touched in DragLayer coordinates
28300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
28400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void move(int touchX, int touchY) {
2857bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationX(touchX - mRegistrationX + (int) mOffsetX);
2867bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationY(touchY - mRegistrationY + (int) mOffsetY);
28700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
28800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
28900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void remove() {
2907bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        if (getParent() != null) {
2917bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung            mDragLayer.removeView(DragView.this);
2927bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        }
2936f13342ffd3f968de9ff86b988621cc91d94adffPatrick Dubroy    }
29400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato}
29500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
296