DragView.java revision 61967cb17f8fa9ee01f93e9f25a1074559b54cf3
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.Matrix;
2600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.graphics.Paint;
27b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chungimport android.graphics.Point;
2861967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chungimport android.graphics.PorterDuff;
2961967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chungimport android.graphics.PorterDuffColorFilter;
30e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohenimport android.graphics.Rect;
3100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onoratoimport android.view.View;
32a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroyimport android.view.animation.DecelerateInterpolator;
3300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
34120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohenimport com.android.launcher.R;
35120980bd00f5eecec5717f49a3d7db96571025a9Adam Cohen
36a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroypublic class DragView extends View {
37867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung    private static float sDragAlpha = 1f;
387bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
3900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Bitmap mBitmap;
40ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    private Bitmap mCrossFadeBitmap;
4100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private Paint mPaint;
4200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mRegistrationX;
4300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private int mRegistrationY;
4400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
45b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    private Point mDragVisualizeOffset = null;
46e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    private Rect mDragRegion = null;
478dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    private DragLayer mDragLayer = null;
48fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    private boolean mHasDrawn = false;
49ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    private float mCrossFadeProgress = 0f;
50a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
51a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    ValueAnimator mAnim;
52a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    private float mOffsetX = 0.0f;
53a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    private float mOffsetY = 0.0f;
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();
7000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
71de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        final Resources res = getResources();
727bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float offsetX = res.getDimensionPixelSize(R.dimen.dragViewOffsetX);
737bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float offsetY = res.getDimensionPixelSize(R.dimen.dragViewOffsetY);
747bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float scaleDps = res.getDimensionPixelSize(R.dimen.dragViewScale);
757bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        final float scale = (width + scaleDps) / width;
76a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
77a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        // Animate the view into the correct position
78a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mAnim = ValueAnimator.ofFloat(0.0f, 1.0f);
797bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        mAnim.setDuration(150);
80a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mAnim.addUpdateListener(new AnimatorUpdateListener() {
81a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy            @Override
82a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy            public void onAnimationUpdate(ValueAnimator animation) {
83a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                final float value = (Float) animation.getAnimatedValue();
84a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
85a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                final int deltaX = (int) ((value * offsetX) - mOffsetX);
86a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                final int deltaY = (int) ((value * offsetY) - mOffsetY);
87a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
88a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                mOffsetX += deltaX;
89a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                mOffsetY += deltaY;
9072d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung                setScaleX(initialScale + (value * (scale - initialScale)));
9172d598400da7cef9c7fc4f99bb1fcd7ff0710011Winson Chung                setScaleY(initialScale + (value * (scale - initialScale)));
92867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung                if (sDragAlpha != 1f) {
93867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung                    setAlpha(sDragAlpha * value + (1f - value));
94867ca62c0e4b811d46734ff940d59c7a787525c8Winson Chung                }
95a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
96a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                if (getParent() == null) {
97a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                    animation.cancel();
98a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                } else {
997bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung                    setTranslationX(getTranslationX() + deltaX);
1007bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung                    setTranslationY(getTranslationY() + deltaY);
101a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy                }
102a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy            }
103a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        });
10400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
1057bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        mBitmap = Bitmap.createBitmap(bitmap, left, top, width, height);
106e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        setDragRegion(new Rect(0, 0, width, height));
10700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
10800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        // The point in our scaled bitmap that the touch events are located
109a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mRegistrationX = registrationX;
110a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mRegistrationY = registrationY;
11162bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy
11262bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        // Force a measure, because Workspace uses getMeasuredHeight() before the layout pass
11362bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        int ms = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
11462bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        measure(ms, ms);
1156cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
11662bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy    }
11762bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy
11862bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy    public float getOffsetY() {
11962bbb3c573fe902940431e4b957c0c4918358d36Patrick Dubroy        return mOffsetY;
12000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
12100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
122a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionLeft() {
123e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.left;
124a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
125a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
126a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionTop() {
127e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.top;
128a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
129a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
130a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionWidth() {
131e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.width();
132a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
133a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
134a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    public int getDragRegionHeight() {
135e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion.height();
136e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    }
137e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen
138b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    public void setDragVisualizeOffset(Point p) {
139b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        mDragVisualizeOffset = p;
140b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    }
141b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung
142b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    public Point getDragVisualizeOffset() {
143b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung        return mDragVisualizeOffset;
144b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung    }
145b8c69f3c17a40adc2d85e8e996f754c383c293dcWinson Chung
146e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    public void setDragRegion(Rect r) {
147e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        mDragRegion = r;
148e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    }
149e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen
150e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen    public Rect getDragRegion() {
151e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen        return mDragRegion;
152a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
153a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
15400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    @Override
15500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
156eebd92496e2fbfbd81ea871862a681929101ba06Joe Onorato        setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
15700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
15800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
15900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    @Override
16000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected void onDraw(Canvas canvas) {
16100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (false) {
16200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            // for debugging
16300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            Paint p = new Paint();
16400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            p.setStyle(Paint.Style.FILL);
16500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            p.setColor(0xaaffffff);
16600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            canvas.drawRect(0, 0, getWidth(), getHeight(), p);
16700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
168a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
169fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen        mHasDrawn = true;
170ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null;
171ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        if (crossFade) {
172ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255;
173ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            mPaint.setAlpha(alpha);
174ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        }
17500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
176ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        if (crossFade) {
177ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            mPaint.setAlpha((int) (255 * mCrossFadeProgress));
178ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.save();
179ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth();
180ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight();
181ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.scale(sX, sY);
182ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint);
183ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            canvas.restore();
184ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        }
185ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    }
186ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen
187ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    public void setCrossFadeBitmap(Bitmap crossFadeBitmap) {
188ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        mCrossFadeBitmap = crossFadeBitmap;
189ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    }
190ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen
191ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen    public void crossFade(int duration) {
192ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        ValueAnimator va = ValueAnimator.ofFloat(0f, 1f);
193ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.setDuration(duration);
194ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.setInterpolator(new DecelerateInterpolator(1.5f));
195ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.addUpdateListener(new AnimatorUpdateListener() {
196ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            @Override
197ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            public void onAnimationUpdate(ValueAnimator animation) {
198ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen                mCrossFadeProgress = animation.getAnimatedFraction();
199ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen            }
200ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        });
201ed66b2bac7447febe2e405b4ce725cae4f6b5988Adam Cohen        va.start();
20200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
20300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
20461967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung    public void setColor(int color) {
2056cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        if (mPaint == null) {
2066cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka            mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
2076cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        }
20861967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        if (color != 0) {
20961967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung            mPaint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
21061967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        } else {
21161967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung            mPaint.setColorFilter(null);
21261967cb17f8fa9ee01f93e9f25a1074559b54cf3Winson Chung        }
21300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        invalidate();
21400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
21500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
216fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    public boolean hasDrawn() {
217fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen        return mHasDrawn;
218fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen    }
219fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen
2203e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    @Override
2213e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    public void setAlpha(float alpha) {
2223e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        super.setAlpha(alpha);
2233e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        mPaint.setAlpha((int) (255 * alpha));
2243e8f811f31a2275e778244427271f77f4116c08bAdam Cohen        invalidate();
2253e8f811f31a2275e778244427271f77f4116c08bAdam Cohen    }
2263e8f811f31a2275e778244427271f77f4116c08bAdam Cohen
22700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
22800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Create a window containing this view and show it.
22900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
23000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * @param windowToken obtained from v.getWindowToken() from one of your views
2318dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchX the x coordinate the user touched in DragLayer coordinates
2328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchY the y coordinate the user touched in DragLayer coordinates
23300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
2348dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen    public void show(int touchX, int touchY) {
2358dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        mDragLayer.addView(this);
2368dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        DragLayer.LayoutParams lp = new DragLayer.LayoutParams(0, 0);
2378dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.width = mBitmap.getWidth();
2388dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.height = mBitmap.getHeight();
2398dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        lp.customPosition = true;
2408dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen        setLayoutParams(lp);
2417bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationX(touchX - mRegistrationX);
2427bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationY(touchY - mRegistrationY);
243a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy        mAnim.start();
24400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
245716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen
2467bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    public void cancelAnimation() {
2477bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        if (mAnim != null && mAnim.isRunning()) {
2487bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung            mAnim.cancel();
2497bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        }
2507bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    }
2517bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
2527bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    public void resetLayoutParams() {
2537bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        mOffsetX = mOffsetY = 0;
2547bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        requestLayout();
2557bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung    }
2567bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung
25700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    /**
25800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     * Move the window containing this view.
25900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     *
2608dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchX the x coordinate the user touched in DragLayer coordinates
2618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen     * @param touchY the y coordinate the user touched in DragLayer coordinates
26200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato     */
26300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void move(int touchX, int touchY) {
2647bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationX(touchX - mRegistrationX + (int) mOffsetX);
2657bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        setTranslationY(touchY - mRegistrationY + (int) mOffsetY);
26600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
26700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
26800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    void remove() {
2697bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        if (getParent() != null) {
2707bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung            mDragLayer.removeView(DragView.this);
2717bd1bbb509f9569fa18d6b4d33242679fd98bc9bWinson Chung        }
2726f13342ffd3f968de9ff86b988621cc91d94adffPatrick Dubroy    }
27300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato}
27400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
275