1792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project/*
2792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *
4792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * you may not use this file except in compliance with the License.
6792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * You may obtain a copy of the License at
7792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *
8792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project *
10792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * See the License for the specific language governing permissions and
14792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project * limitations under the License.
15792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project */
16792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
17792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpackage com.android.music;
18792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
19792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.Context;
20792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.content.SharedPreferences;
2117634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissenimport android.content.res.Resources;
22792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.Bitmap;
23792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.PixelFormat;
24792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.graphics.Rect;
25355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissenimport android.graphics.drawable.Drawable;
26355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissenimport android.graphics.drawable.LevelListDrawable;
27792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.util.AttributeSet;
28355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissenimport android.util.Log;
29792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.GestureDetector;
30792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.Gravity;
31792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.MotionEvent;
32792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.View;
33792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.ViewConfiguration;
34792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.ViewGroup;
35792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.WindowManager;
36792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.view.GestureDetector.SimpleOnGestureListener;
37792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.AdapterView;
38792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.ImageView;
39792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectimport android.widget.ListView;
40792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
41792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Projectpublic class TouchInterceptor extends ListView {
42792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
43b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen    private ImageView mDragView;
44792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private WindowManager mWindowManager;
45792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private WindowManager.LayoutParams mWindowParams;
46355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    /**
47355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen     * At which position is the item currently being dragged. Note that this
48355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen     * takes in to account header items.
49355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen     */
50355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private int mDragPos;
51355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    /**
52355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen     * At which position was the item being dragged originally
53355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen     */
54355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private int mSrcDragPos;
55355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private int mDragPointX;    // at what x offset inside the item did the user grab it
56355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private int mDragPointY;    // at what y offset inside the item did the user grab it
57355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private int mXOffset;  // the difference between screen coordinates and coordinates in this view
58355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private int mYOffset;  // the difference between screen coordinates and coordinates in this view
59792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private DragListener mDragListener;
60792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private DropListener mDropListener;
61792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private RemoveListener mRemoveListener;
62792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private int mUpperBound;
63792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private int mLowerBound;
64792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private int mHeight;
65792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private GestureDetector mGestureDetector;
66792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static final int FLING = 0;
67792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private static final int SLIDE = 1;
68355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private static final int TRASH = 2;
69792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private int mRemoveMode = -1;
70792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private Rect mTempRect = new Rect();
71792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private Bitmap mDragBitmap;
72792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private final int mTouchSlop;
7317634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen    private int mItemHeightNormal;
7417634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen    private int mItemHeightExpanded;
75ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen    private int mItemHeightHalf;
76355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private Drawable mTrashcan;
77792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
78792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public TouchInterceptor(Context context, AttributeSet attrs) {
79792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        super(context, attrs);
80792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        SharedPreferences pref = context.getSharedPreferences("Music", 3);
81792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mRemoveMode = pref.getInt("deletemode", -1);
82792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
8317634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen        Resources res = getResources();
8417634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen        mItemHeightNormal = res.getDimensionPixelSize(R.dimen.normal_height);
85ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen        mItemHeightHalf = mItemHeightNormal / 2;
8617634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen        mItemHeightExpanded = res.getDimensionPixelSize(R.dimen.expanded_height);
87792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
88792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
89792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    @Override
90792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public boolean onInterceptTouchEvent(MotionEvent ev) {
91792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (mRemoveListener != null && mGestureDetector == null) {
92792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            if (mRemoveMode == FLING) {
93792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                mGestureDetector = new GestureDetector(getContext(), new SimpleOnGestureListener() {
94792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    @Override
95792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
96792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            float velocityY) {
97792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        if (mDragView != null) {
98792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            if (velocityX > 1000) {
99792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                Rect r = mTempRect;
100792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                mDragView.getDrawingRect(r);
101792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                if ( e2.getX() > r.right * 2 / 3) {
102792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                    // fast fling right with release near the right edge of the screen
103792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                    stopDragging();
104355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                    mRemoveListener.remove(mSrcDragPos);
105792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                    unExpandViews(true);
106792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                }
107792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            }
108792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            // flinging while dragging should have no effect
109792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            return true;
110792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
111792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        return false;
112792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    }
113792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                });
114792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
115792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
116792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (mDragListener != null || mDropListener != null) {
117792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            switch (ev.getAction()) {
118792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                case MotionEvent.ACTION_DOWN:
119792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int x = (int) ev.getX();
120792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int y = (int) ev.getY();
121792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int itemnum = pointToPosition(x, y);
122792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    if (itemnum == AdapterView.INVALID_POSITION) {
123792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        break;
124792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    }
125792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    ViewGroup item = (ViewGroup) getChildAt(itemnum - getFirstVisiblePosition());
126355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    mDragPointX = x - item.getLeft();
127355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    mDragPointY = y - item.getTop();
128355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    mXOffset = ((int)ev.getRawX()) - x;
129355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    mYOffset = ((int)ev.getRawY()) - y;
130355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    // The left side of the item is the grabber for dragging the item
131355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    if (x < 64) {
132792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        item.setDrawingCacheEnabled(true);
133792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        // Create a copy of the drawing cache so that it does not get recycled
134792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        // by the framework when the list tries to clean up memory
135792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());
136355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                        startDragging(bitmap, x, y);
137792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        mDragPos = itemnum;
138355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                        mSrcDragPos = mDragPos;
139792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        mHeight = getHeight();
140792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        int touchSlop = mTouchSlop;
141792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        mUpperBound = Math.min(y - touchSlop, mHeight / 3);
142792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        mLowerBound = Math.max(y + touchSlop, mHeight * 2 /3);
143792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        return false;
144792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    }
145197ad25d057bfa4390f0f732d09c0d9f81c54582Marco Nelissen                    stopDragging();
146792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
147792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
148792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
149792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        return super.onInterceptTouchEvent(ev);
150792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
151792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
152792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    /*
153792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * pointToPosition() doesn't consider invisible views, but we
154792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * need to, so implement a slightly different version.
155792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     */
156792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private int myPointToPosition(int x, int y) {
157ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen
158ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen        if (y < 0) {
159ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen            // when dragging off the top of the screen, calculate position
160ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen            // by going back from a visible item
161ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen            int pos = myPointToPosition(x, y + mItemHeightNormal);
162ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen            if (pos > 0) {
163ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen                return pos - 1;
164ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen            }
165ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen        }
166ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen
167792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        Rect frame = mTempRect;
168792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        final int count = getChildCount();
169792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        for (int i = count - 1; i >= 0; i--) {
170792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            final View child = getChildAt(i);
171792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            child.getHitRect(frame);
172792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            if (frame.contains(x, y)) {
173792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                return getFirstVisiblePosition() + i;
174792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
175792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
176792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        return INVALID_POSITION;
177792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
178792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
179792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private int getItemForPosition(int y) {
180355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        int adjustedy = y - mDragPointY - mItemHeightHalf;
181792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        int pos = myPointToPosition(0, adjustedy);
182792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (pos >= 0) {
183355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            if (pos <= mSrcDragPos) {
184792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                pos += 1;
185792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
186792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        } else if (adjustedy < 0) {
187ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen            // this shouldn't happen anymore now that myPointToPosition deals
188ea9e2c80576d41828bc457bcbca73f197d247a8aMarco Nelissen            // with this situation
189792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            pos = 0;
190792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
191792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        return pos;
192792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
193792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
194792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private void adjustScrollBounds(int y) {
195792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (y >= mHeight / 3) {
196792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            mUpperBound = mHeight / 3;
197792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
198792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (y <= mHeight * 2 / 3) {
199792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            mLowerBound = mHeight * 2 / 3;
200792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
201792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
202792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
203792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    /*
204792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * Restore size and visibility for all listitems
205792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     */
206792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private void unExpandViews(boolean deletion) {
207792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        for (int i = 0;; i++) {
208792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            View v = getChildAt(i);
209792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            if (v == null) {
210792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                if (deletion) {
211792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    // HACK force update of mItemCount
212792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int position = getFirstVisiblePosition();
213792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int y = getChildAt(0).getTop();
214792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    setAdapter(getAdapter());
215792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    setSelectionFromTop(position, y);
216792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    // end hack
217792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                }
218add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                try {
219add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                    layoutChildren(); // force children to be recreated where needed
220add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                    v = getChildAt(i);
221add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                } catch (IllegalStateException ex) {
222add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                    // layoutChildren throws this sometimes, presumably because we're
223add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                    // in the process of being torn down but are still getting touch
224add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                    // events
225add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                }
226792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                if (v == null) {
227add0649249b57e025e9d7d26f1ae16f3c0bfb3ceMarco Nelissen                    return;
228792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                }
229792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
230792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            ViewGroup.LayoutParams params = v.getLayoutParams();
23117634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen            params.height = mItemHeightNormal;
232792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            v.setLayoutParams(params);
233792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            v.setVisibility(View.VISIBLE);
234792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
235792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
236792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
237792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    /* Adjust visibility and size to make it appear as though
238792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * an item is being dragged around and other items are making
239792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * room for it:
240792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * If dropping the item would result in it still being in the
241792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * same place, then make the dragged listitem's size normal,
242792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * but make the item invisible.
243792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * Otherwise, if the dragged listitem is still on screen, make
244792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * it as small as possible and expand the item below the insert
245792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * point.
246792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * If the dragged item is not on screen, only expand the item
247792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     * below the current insertpoint.
248792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project     */
249792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private void doExpansion() {
250792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        int childnum = mDragPos - getFirstVisiblePosition();
251355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        if (mDragPos > mSrcDragPos) {
252792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            childnum++;
253792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
254355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        int numheaders = getHeaderViewsCount();
255792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
256355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        View first = getChildAt(mSrcDragPos - getFirstVisiblePosition());
257792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        for (int i = 0;; i++) {
258792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            View vv = getChildAt(i);
259792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            if (vv == null) {
260792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                break;
261792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
262355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen
26317634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen            int height = mItemHeightNormal;
264792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            int visibility = View.VISIBLE;
265355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            if (mDragPos < numheaders && i == numheaders) {
266355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                // dragging on top of the header item, so adjust the item below
267355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                // instead
268355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                if (vv.equals(first)) {
269355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    visibility = View.INVISIBLE;
270355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                } else {
271355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    height = mItemHeightExpanded;
272355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                }
273355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            } else if (vv.equals(first)) {
274792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                // processing the item that is being dragged
275355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                if (mDragPos == mSrcDragPos || getPositionForView(vv) == getCount() - 1) {
276792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    // hovering over the original location
277792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    visibility = View.INVISIBLE;
278792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                } else {
279792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    // not hovering over it
280355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    // Ideally the item would be completely gone, but neither
281355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    // setting its size to 0 nor settings visibility to GONE
282355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                    // has the desired effect.
283792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    height = 1;
284792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                }
285792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            } else if (i == childnum) {
286355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                if (mDragPos >= numheaders && mDragPos < getCount() - 1) {
28717634b248a4494616504c02128b1d3efc1ce42d4Marco Nelissen                    height = mItemHeightExpanded;
288792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                }
289792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
290792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            ViewGroup.LayoutParams params = vv.getLayoutParams();
291792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            params.height = height;
292792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            vv.setLayoutParams(params);
293792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            vv.setVisibility(visibility);
294792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
295792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
296792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
297792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    @Override
298792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public boolean onTouchEvent(MotionEvent ev) {
299792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (mGestureDetector != null) {
300792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            mGestureDetector.onTouchEvent(ev);
301792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
302792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if ((mDragListener != null || mDropListener != null) && mDragView != null) {
303792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            int action = ev.getAction();
304792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            switch (action) {
305792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                case MotionEvent.ACTION_UP:
306792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                case MotionEvent.ACTION_CANCEL:
307792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    Rect r = mTempRect;
308792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    mDragView.getDrawingRect(r);
309792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    stopDragging();
310792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    if (mRemoveMode == SLIDE && ev.getX() > r.right * 3 / 4) {
311792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        if (mRemoveListener != null) {
312355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            mRemoveListener.remove(mSrcDragPos);
313792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
314792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        unExpandViews(true);
315792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    } else {
316792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        if (mDropListener != null && mDragPos >= 0 && mDragPos < getCount()) {
317355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            mDropListener.drop(mSrcDragPos, mDragPos);
318792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
319792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        unExpandViews(false);
320792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    }
321792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
322792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
323792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                case MotionEvent.ACTION_DOWN:
324792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                case MotionEvent.ACTION_MOVE:
325792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int x = (int) ev.getX();
326792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int y = (int) ev.getY();
327792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    dragView(x, y);
328792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    int itemnum = getItemForPosition(y);
329792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    if (itemnum >= 0) {
330792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        if (action == MotionEvent.ACTION_DOWN || itemnum != mDragPos) {
331792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            if (mDragListener != null) {
332792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                                mDragListener.drag(mDragPos, itemnum);
333792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            }
334792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            mDragPos = itemnum;
335792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            doExpansion();
336792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
337792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        int speed = 0;
338792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        adjustScrollBounds(y);
339792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        if (y > mLowerBound) {
340792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            // scroll the list up a bit
341355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            if (getLastVisiblePosition() < getCount() - 1) {
342355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                speed = y > (mHeight + mLowerBound) / 2 ? 16 : 4;
343355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            } else {
344355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                speed = 1;
345355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            }
346792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        } else if (y < mUpperBound) {
347792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            // scroll the list down a bit
348792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                            speed = y < mUpperBound / 2 ? -16 : -4;
349355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            if (getFirstVisiblePosition() == 0
350355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                    && getChildAt(0).getTop() >= getPaddingTop()) {
351355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                // if we're already at the top, don't try to scroll, because
352355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                // it causes the framework to do some extra drawing that messes
353355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                // up our animation
354355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                                speed = 0;
355355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            }
356792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
357792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        if (speed != 0) {
358355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                            smoothScrollBy(speed, 30);
359792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                        }
360792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    }
361792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                    break;
362792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
363792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            return true;
364792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
365792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        return super.onTouchEvent(ev);
366792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
367792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
368355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    private void startDragging(Bitmap bm, int x, int y) {
369b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen        stopDragging();
370b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen
371792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowParams = new WindowManager.LayoutParams();
372355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        mWindowParams.gravity = Gravity.TOP | Gravity.LEFT;
373355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        mWindowParams.x = x - mDragPointX + mXOffset;
374355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        mWindowParams.y = y - mDragPointY + mYOffset;
375792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
376792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
377792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
378792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
379792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
380792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
38109115f63680fc2e881fd523276bb4afd9277f921Marco Nelissen                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
38209115f63680fc2e881fd523276bb4afd9277f921Marco Nelissen                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
383792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowParams.format = PixelFormat.TRANSLUCENT;
384792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowParams.windowAnimations = 0;
385792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
3863416c22c91849b2d860dd07241ecbdf3ae7edeafMarco Nelissen        Context context = getContext();
3873416c22c91849b2d860dd07241ecbdf3ae7edeafMarco Nelissen        ImageView v = new ImageView(context);
388355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        //int backGroundColor = context.getResources().getColor(R.color.dragndrop_background);
389355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        //v.setBackgroundColor(backGroundColor);
390355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        v.setBackgroundResource(R.drawable.playlist_tile_drag);
391355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        v.setPadding(0, 0, 0, 0);
392792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        v.setImageBitmap(bm);
393792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mDragBitmap = bm;
394792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
395355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
396792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowManager.addView(v, mWindowParams);
397792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mDragView = v;
398792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
399792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
400792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private void dragView(int x, int y) {
401792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (mRemoveMode == SLIDE) {
402792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            float alpha = 1.0f;
403792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            int width = mDragView.getWidth();
404792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            if (x > width / 2) {
405792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project                alpha = ((float)(width - x)) / (width / 2);
406792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            }
407792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            mWindowParams.alpha = alpha;
408792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
409355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen
410355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        if (mRemoveMode == FLING || mRemoveMode == TRASH) {
411355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            mWindowParams.x = x - mDragPointX + mXOffset;
412355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        } else {
413355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            mWindowParams.x = 0;
41409115f63680fc2e881fd523276bb4afd9277f921Marco Nelissen        }
415355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        mWindowParams.y = y - mDragPointY + mYOffset;
416792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mWindowManager.updateViewLayout(mDragView, mWindowParams);
417355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen
418355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        if (mTrashcan != null) {
419355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            int width = mDragView.getWidth();
420355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            if (y > getHeight() * 3 / 4) {
421355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                mTrashcan.setLevel(2);
422355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            } else if (width > 0 && x > width / 4) {
423355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                mTrashcan.setLevel(1);
424355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            } else {
425355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen                mTrashcan.setLevel(0);
426355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            }
427355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        }
428792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
429792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
430792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    private void stopDragging() {
431b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen        if (mDragView != null) {
432355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            mDragView.setVisibility(GONE);
433355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
434b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen            wm.removeView(mDragView);
435b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen            mDragView.setImageDrawable(null);
436b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen            mDragView = null;
437b5e252efe636571789d8ea7d9fe9800ad88260ccMarco Nelissen        }
438792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        if (mDragBitmap != null) {
439792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            mDragBitmap.recycle();
440792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project            mDragBitmap = null;
441792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        }
442355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        if (mTrashcan != null) {
443355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen            mTrashcan.setLevel(0);
444355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        }
445792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
446355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen
447355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    public void setTrashcan(Drawable trash) {
448355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        mTrashcan = trash;
449355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen        mRemoveMode = TRASH;
450355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen    }
451355e134c59525cdd5a5ca8db434ff9ccbb81fa2aMarco Nelissen
452792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public void setDragListener(DragListener l) {
453792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mDragListener = l;
454792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
455792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
456792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public void setDropListener(DropListener l) {
457792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mDropListener = l;
458792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
459792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
460792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public void setRemoveListener(RemoveListener l) {
461792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        mRemoveListener = l;
462792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
463792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project
464792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public interface DragListener {
465792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        void drag(int from, int to);
466792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
467792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public interface DropListener {
468792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        void drop(int from, int to);
469792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
470792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    public interface RemoveListener {
471792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project        void remove(int which);
472792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project    }
473792a2206a4f05f6bd13fce902d3663892d2947afThe Android Open Source Project}
474