Folder.java revision 76fc085d28178a5d4fb3787ede956281a2cc3179
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/*
231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License.
631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at
731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and
1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License.
1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2;
1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
19df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.Animator;
20df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.AnimatorListenerAdapter;
21df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.ObjectAnimator;
22df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.PropertyValuesHolder;
23df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.ValueAnimator;
24df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener;
2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context;
2676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.content.res.Resources;
27fb5411e98278d461b78aea0663d3e85f7a9e8a15Romain Guyimport android.graphics.Rect;
28badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohenimport android.graphics.drawable.Drawable;
2931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet;
3076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.ActionMode;
3176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.KeyEvent;
32df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.view.LayoutInflater;
3376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.Menu;
3476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.MenuItem;
350c872ba544ecfd9b106bb66137da8680927590deAdam Cohenimport android.view.MotionEvent;
3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View;
3731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View.OnClickListener;
382801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.view.animation.AccelerateInterpolator;
392801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.view.animation.DecelerateInterpolator;
4076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.inputmethod.EditorInfo;
4176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.inputmethod.InputMethodManager;
4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.AdapterView;
4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.LinearLayout;
44df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.widget.TextView;
4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.AdapterView.OnItemClickListener;
4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.AdapterView.OnItemLongClickListener;
4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
48edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guyimport com.android.launcher.R;
49a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport com.android.launcher2.FolderInfo.FolderListener;
50edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy
51c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList;
52c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen
5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Represents a set of icons chosen by the user or generated by the system.
5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectpublic class Folder extends LinearLayout implements DragSource, OnItemLongClickListener,
5776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        OnItemClickListener, OnClickListener, View.OnLongClickListener, DropTarget, FolderListener,
5876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        TextView.OnEditorActionListener {
5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
6000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected DragController mDragController;
61df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    protected Launcher mLauncher;
6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    protected FolderInfo mInfo;
6531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
66df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    private static final String TAG = "Launcher.Folder";
67df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
68df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    static final int STATE_NONE = -1;
69df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    static final int STATE_SMALL = 0;
70df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    static final int STATE_ANIMATING = 1;
71df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    static final int STATE_OPEN = 2;
72df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
73df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    private int mExpandDuration;
74df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    protected CellLayout mContent;
75df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    private final LayoutInflater mInflater;
76df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    private final IconCache mIconCache;
77df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    private int mState = STATE_NONE;
78a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen    private int[] mDragItemPosition = new int[2];
792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private static final int FULL_GROW = 0;
802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private static final int PARTIAL_GROW = 1;
81bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private static final int REORDER_ANIMATION_DURATION = 230;
82bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private static final int ON_EXIT_CLOSE_DELAY = 800;
832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private int mMode = PARTIAL_GROW;
842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private boolean mRearrangeOnClose = false;
852801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private FolderIcon mFolderIcon;
862801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private int mMaxCountX;
872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private int mMaxCountY;
882801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private Rect mNewSize = new Rect();
897c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen    private ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
90badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen    private Drawable mIconDrawable;
917c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen    boolean mItemsInvalidated = false;
92bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private ShortcutInfo mCurrentDragInfo;
93bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private View mCurrentDragView;
94bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    boolean mSuppressOnAdd = false;
95bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private int[] mTargetCell = new int[2];
96bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private int[] mPreviousTargetCell = new int[2];
97bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private int[] mEmptyCell = new int[2];
98bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private Alarm mReorderAlarm = new Alarm();
99bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private Alarm mOnExitAlarm = new Alarm();
10076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    private TextView mFolderName;
10176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    private int mFolderNameHeight;
10276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
10376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    private boolean mIsEditingName = false;
10476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    private InputMethodManager mInputMethodManager;
105df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Used to inflate the Workspace from XML.
10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param context The application's context.
11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param attrs The attribtues set containing the Workspace's customization values.
11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
11231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public Folder(Context context, AttributeSet attrs) {
11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super(context, attrs);
11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        setAlwaysDrawnWithCacheEnabled(false);
115df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        mInflater = LayoutInflater.from(context);
116df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        mIconCache = ((LauncherApplication)context.getApplicationContext()).getIconCache();
1172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mMaxCountX = LauncherModel.getCellCountX() - 1;
1182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mMaxCountY = LauncherModel.getCellCountY() - 1;
11976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
12076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mInputMethodManager = (InputMethodManager)
12176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
12276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
12376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        Resources res = getResources();
12476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mExpandDuration = res.getInteger(R.integer.config_folderAnimDuration);
12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    protected void onFinishInflate() {
12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super.onFinishInflate();
130df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        mContent = (CellLayout) findViewById(R.id.folder_content);
1312801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mContent.setGridSize(0, 0);
1322801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mContent.enableHardwareLayers();
13376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName = (TextView) findViewById(R.id.folder_name);
13476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
13576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        // We find out how tall the text view wants to be (it is set to wrap_content), so that
13676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        // we can allocate the appropriate amount of space for it.
13776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        int measureSpec = MeasureSpec.UNSPECIFIED;
13876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.measure(measureSpec, measureSpec);
13976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderNameHeight = mFolderName.getMeasuredHeight();
14076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
14176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        // We disable action mode for now since it messes up the view on phones
14276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback);
14376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.setCursorVisible(false);
14476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.setOnEditorActionListener(this);
14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1462801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
14776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
14876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
14976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            return false;
15076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        }
15176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
15276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
15376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            return false;
15476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        }
15576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
15676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        public void onDestroyActionMode(ActionMode mode) {
15776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        }
15876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
15976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
16076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            return false;
16176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        }
16276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    };
16376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void onItemClick(AdapterView parent, View v, int position, long id) {
1650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        ShortcutInfo app = (ShortcutInfo) parent.getItemAtPosition(position);
166fb5411e98278d461b78aea0663d3e85f7a9e8a15Romain Guy        int[] pos = new int[2];
167fb5411e98278d461b78aea0663d3e85f7a9e8a15Romain Guy        v.getLocationOnScreen(pos);
168fb5411e98278d461b78aea0663d3e85f7a9e8a15Romain Guy        app.intent.setSourceBounds(new Rect(pos[0], pos[1],
169fb5411e98278d461b78aea0663d3e85f7a9e8a15Romain Guy                pos[0] + v.getWidth(), pos[1] + v.getHeight()));
170f984e853f253c76a7a636a094680bb01c4b8ffb8Joe Onorato        mLauncher.startActivitySafely(app.intent, app);
17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void onClick(View v) {
174df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        Object tag = v.getTag();
175df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        if (tag instanceof ShortcutInfo) {
176df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            // refactor this code from Folder
177df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            ShortcutInfo item = (ShortcutInfo) tag;
178df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            int[] pos = new int[2];
179df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            v.getLocationOnScreen(pos);
180df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            item.intent.setSourceBounds(new Rect(pos[0], pos[1],
181df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));
182df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            mLauncher.startActivitySafely(item.intent, item);
183df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        }
18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
18676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    private Rect mHitRect = new Rect();
18776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public boolean onInterceptTouchEvent(MotionEvent ev) {
18876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
18976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            mFolderName.getHitRect(mHitRect);
19076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            if (mHitRect.contains((int) ev.getX(), (int) ev.getY()) && !mIsEditingName) {
19176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                startEditingFolderName();
19276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            }
19376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        }
19476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        return false;
19576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
19676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
19731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public boolean onLongClick(View v) {
198df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        Object tag = v.getTag();
199df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        if (tag instanceof ShortcutInfo) {
200df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            ShortcutInfo item = (ShortcutInfo) tag;
201df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            if (!v.isInTouchMode()) {
202df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen                return false;
203df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            }
204df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
205df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            mLauncher.getWorkspace().onDragStartedWithItem(v);
206df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            mDragController.startDrag(v, this, item, DragController.DRAG_ACTION_COPY);
207a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen            mDragItemPosition[0] = item.cellX;
208a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen            mDragItemPosition[1] = item.cellY;
209badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen            mIconDrawable = ((TextView) v).getCompoundDrawables()[1];
21076078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen
21176078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen            mCurrentDragInfo = item;
212bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mEmptyCell[0] = item.cellX;
213bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mEmptyCell[1] = item.cellY;
214bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mCurrentDragView = v;
215bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mContent.removeView(mCurrentDragView);
216bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mInfo.remove(item);
217df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        }
21831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return true;
21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
22176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public boolean isEditingName() {
22276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        return mIsEditingName;
22376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
22476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
22576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public void startEditingFolderName() {
22676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.setCursorVisible(true);
22776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mIsEditingName = true;
22876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
22976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
23076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public void dismissEditingName() {
23176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
23276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        doneEditingFolderName(true);
23376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
23476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
23576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public void doneEditingFolderName(boolean commit) {
23676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mInfo.setTitle(mFolderName.getText());
23776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        LauncherModel.updateItemInDatabase(mLauncher, mInfo);
23876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.setCursorVisible(false);
23976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.clearFocus();
24076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mIsEditingName = false;
24176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
24276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
24376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
24476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        if (actionId == EditorInfo.IME_ACTION_DONE) {
24576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            dismissEditingName();
24676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen            return true;
24776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        }
24876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        return false;
24976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
25076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
25176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public View getEditTextRegion() {
25276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        return mFolderName;
25376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
25476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen
255badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen    public Drawable getDragDrawable() {
256badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen        return mIconDrawable;
257badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen    }
258badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen
2590c872ba544ecfd9b106bb66137da8680927590deAdam Cohen    /**
2600c872ba544ecfd9b106bb66137da8680927590deAdam Cohen     * We need to handle touch events to prevent them from falling through to the workspace below.
2610c872ba544ecfd9b106bb66137da8680927590deAdam Cohen     */
2620c872ba544ecfd9b106bb66137da8680927590deAdam Cohen    @Override
2630c872ba544ecfd9b106bb66137da8680927590deAdam Cohen    public boolean onTouchEvent(MotionEvent ev) {
2640c872ba544ecfd9b106bb66137da8680927590deAdam Cohen        return true;
2650c872ba544ecfd9b106bb66137da8680927590deAdam Cohen    }
2660c872ba544ecfd9b106bb66137da8680927590deAdam Cohen
26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
26831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!view.isInTouchMode()) {
26931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return false;
27031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
27131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
2720589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        ShortcutInfo app = (ShortcutInfo) parent.getItemAtPosition(position);
27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
27400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragController.startDrag(view, this, app, DragController.DRAG_ACTION_COPY);
27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mLauncher.closeFolder(this);
27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return true;
27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
27900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setDragController(DragController dragController) {
28000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragController = dragController;
28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
283a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    public void onDragViewVisible() {
284a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy    }
285a669d79d0dcf034651ce305a8cd334272bec3374Patrick Dubroy
28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void setLauncher(Launcher launcher) {
28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mLauncher = launcher;
28831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
2892801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
2902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    void setFolderIcon(FolderIcon icon) {
2912801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mFolderIcon = icon;
2922801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
2932801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return the FolderInfo object associated with this folder
29631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
29731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    FolderInfo getInfo() {
29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return mInfo;
29931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
30131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void onOpen() {
302df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        // When the folder opens, we need to refresh the GridView's selection by
303df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        // forcing a layout
304df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        // TODO: find out if this is still necessary
305df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        mContent.requestLayout();
30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
30831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void onClose() {
30976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        CellLayoutChildren clc = (CellLayoutChildren) getParent();
31076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        final CellLayout cellLayout = (CellLayout) clc.getParent();
31176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        cellLayout.removeViewWithoutMarkingCells(Folder.this);
31276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        clearFocus();
31331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
31431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void bind(FolderInfo info) {
31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mInfo = info;
317df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        ArrayList<ShortcutInfo> children = info.contents;
3187c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        setupContentForNumItems(children.size());
319df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        for (int i = 0; i < children.size(); i++) {
320df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            ShortcutInfo child = (ShortcutInfo) children.get(i);
3217c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            createAndAddShortcut(child);
322df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        }
3234dbe6d993485a702505ee4895db94aaa89655f2cAdam Cohen        mItemsInvalidated = true;
324a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen        mInfo.addListener(this);
32576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        mFolderName.setText(mInfo.title);
326df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
327df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
328df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    /**
329df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     * Creates a new UserFolder, inflated from R.layout.user_folder.
330df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     *
331df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     * @param context The application's context.
332df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     *
333df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     * @return A new UserFolder.
334df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     */
335df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    static Folder fromXml(Context context) {
336df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null);
337df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
338df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
339df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    /**
340df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     * This method is intended to make the UserFolder to be visually identical in size and position
341df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     * to its associated FolderIcon. This allows for a seamless transition into the expanded state.
342df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen     */
343df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    private void positionAndSizeAsIcon() {
344df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        if (!(getParent() instanceof CellLayoutChildren)) return;
345df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
3462801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams();
347df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
348df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
3492801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (mMode == PARTIAL_GROW) {
3502801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            setScaleX(0.8f);
3512801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            setScaleY(0.8f);
3522801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            setAlpha(0f);
3532801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        } else {
3542801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.width = iconLp.width;
3552801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.height = iconLp.height;
3562801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.x = iconLp.x;
3572801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.y = iconLp.y;
3582801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            mContent.setAlpha(0);
3592801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
360df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        mState = STATE_SMALL;
361df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
362df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
363df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    public void animateOpen() {
364df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        if (mState != STATE_SMALL) {
365df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            positionAndSizeAsIcon();
366df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        }
367df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        if (!(getParent() instanceof CellLayoutChildren)) return;
368df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
3692801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        ObjectAnimator oa;
370df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
371df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
3722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        centerAboutIcon();
3732801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (mMode == PARTIAL_GROW) {
3742801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1);
3752801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
3762801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
3772801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);
3782801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        } else {
3792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mNewSize.width());
3802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mNewSize.height());
3812801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", mNewSize.left);
3822801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", mNewSize.top);
3832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
3842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            oa.addUpdateListener(new AnimatorUpdateListener() {
3852801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                public void onAnimationUpdate(ValueAnimator animation) {
3862801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                    requestLayout();
3872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                }
3882801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            });
3892801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
3902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);
3912801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
3922801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            alphaOa.setDuration(mExpandDuration);
3932801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            alphaOa.setInterpolator(new AccelerateInterpolator(2.0f));
3942801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            alphaOa.start();
3952801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
396df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
3972801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        oa.addListener(new AnimatorListenerAdapter() {
398df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            @Override
399df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            public void onAnimationStart(Animator animation) {
400df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen                mState = STATE_ANIMATING;
401df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            }
402df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            @Override
403df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            public void onAnimationEnd(Animator animation) {
4042801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                mState = STATE_OPEN;
405df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            }
406df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        });
4072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        oa.setDuration(mExpandDuration);
4082801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        oa.start();
409df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
410df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
411df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    public void animateClosed() {
412df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        if (!(getParent() instanceof CellLayoutChildren)) return;
413df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
4142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        ObjectAnimator oa;
4152801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (mMode == PARTIAL_GROW) {
4162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);
4172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f);
4182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f);
4192801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);
4202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        } else {
4212801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams();
4222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
4232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
4242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", iconLp.width);
4252801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", iconLp.height);
4262801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder x = PropertyValuesHolder.ofInt("x",iconLp.x);
4272801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", iconLp.y);
4282801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
4292801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            oa.addUpdateListener(new AnimatorUpdateListener() {
4302801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                public void onAnimationUpdate(ValueAnimator animation) {
4312801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                    requestLayout();
4322801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                }
4332801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            });
4342801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
4352801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f);
4362801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha);
4372801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            alphaOa.setDuration(mExpandDuration);
4382801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            alphaOa.setInterpolator(new DecelerateInterpolator(2.0f));
4392801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            alphaOa.start();
4402801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
441df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
4422801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        oa.addListener(new AnimatorListenerAdapter() {
443df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            @Override
444df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            public void onAnimationEnd(Animator animation) {
44576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                onClose();
4462801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                onCloseComplete();
4472801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                mState = STATE_SMALL;
448df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            }
449df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            @Override
450df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            public void onAnimationStart(Animator animation) {
451df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen                mState = STATE_ANIMATING;
452df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            }
453df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        });
4542801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        oa.setDuration(mExpandDuration);
4552801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        oa.start();
456df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
457df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
458df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    void notifyDataSetChanged() {
459df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        // recreate all the children if the data set changes under us. We may want to do this more
460df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        // intelligently (ie just removing the views that should no longer exist)
461df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        mContent.removeAllViewsInLayout();
462df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        bind(mInfo);
463df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
464df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
465cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen    public boolean acceptDrop(DragObject d) {
466cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen        final ItemInfo item = (ItemInfo) d.dragInfo;
467df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        final int itemType = item.itemType;
4682801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
4692801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                    itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) &&
4702801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                    !isFull());
471df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
472df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
473df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    protected boolean findAndSetEmptyCells(ShortcutInfo item) {
474df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        int[] emptyCell = new int[2];
475df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        if (mContent.findCellForSpan(emptyCell, item.spanX, item.spanY)) {
476df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            item.cellX = emptyCell[0];
477df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            item.cellY = emptyCell[1];
478df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            return true;
479df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        } else {
480df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            return false;
481df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        }
482df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
483df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
484df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    protected void createAndAddShortcut(ShortcutInfo item) {
485df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        final TextView textView =
486df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            (TextView) mInflater.inflate(R.layout.application_boxed, this, false);
487df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        textView.setCompoundDrawablesWithIntrinsicBounds(null,
488df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen                new FastBitmapDrawable(item.getIcon(mIconCache)), null, null);
489df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        textView.setText(item.title);
490df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        textView.setTag(item);
491df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
492df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        textView.setOnClickListener(this);
493df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        textView.setOnLongClickListener(this);
494df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
495df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        CellLayout.LayoutParams lp =
496df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen            new CellLayout.LayoutParams(item.cellX, item.cellY, item.spanX, item.spanY);
497df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        boolean insert = false;
498df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        mContent.addViewToCellLayout(textView, insert ? 0 : -1, (int)item.id, lp, true);
499df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
500df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
501cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen    public void onDragEnter(DragObject d) {
502bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mPreviousTargetCell[0] = -1;
503bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mPreviousTargetCell[1] = -1;
5042801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mContent.onDragEnter();
505bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mOnExitAlarm.cancelAlarm();
506df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
507df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
508bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    OnAlarmListener mReorderAlarmListener = new OnAlarmListener() {
509bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        public void onAlarm(Alarm alarm) {
510bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            realTimeReorder(mEmptyCell, mTargetCell);
511bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
512bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    };
513bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
514bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    boolean readingOrderGreaterThan(int[] v1, int[] v2) {
515bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (v1[1] > v2[1] || (v1[1] == v2[1] && v1[0] > v2[0])) {
516bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            return true;
517bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        } else {
518bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            return false;
519bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
520df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
521df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
522bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private void realTimeReorder(int[] empty, int[] target) {
523bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        boolean wrap;
524bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        int startX;
525bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        int endX;
526bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        int startY;
52776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        int delay = 0;
52876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        float delayAmount = 30;
529bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (readingOrderGreaterThan(target, empty)) {
530bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            wrap = empty[0] >= mContent.getCountX() - 1;
531bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            startY = wrap ? empty[1] + 1 : empty[1];
532bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            for (int y = startY; y <= target[1]; y++) {
533bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                startX = y == empty[1] ? empty[0] + 1 : 0;
534bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                endX = y < target[1] ? mContent.getCountX() - 1 : target[0];
535bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                for (int x = startX; x <= endX; x++) {
536bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                    View v = mContent.getChildAt(x,y);
537bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                    if (mContent.animateChildToPosition(v, empty[0], empty[1],
53876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                            REORDER_ANIMATION_DURATION, delay)) {
539bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                        empty[0] = x;
540bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                        empty[1] = y;
54176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                        delay += delayAmount;
54276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                        delayAmount *= 0.9;
543bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                    }
544bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                }
545bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            }
546bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        } else {
547bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            wrap = empty[0] == 0;
548bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            startY = wrap ? empty[1] - 1 : empty[1];
549bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            for (int y = startY; y >= target[1]; y--) {
550bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                startX = y == empty[1] ? empty[0] - 1 : mContent.getCountX() - 1;
551bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                endX = y > target[1] ? 0 : target[0];
552bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                for (int x = startX; x >= endX; x--) {
553bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                    View v = mContent.getChildAt(x,y);
554bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                    if (mContent.animateChildToPosition(v, empty[0], empty[1],
55576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                            REORDER_ANIMATION_DURATION, delay)) {
556bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                        empty[0] = x;
557bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                        empty[1] = y;
55876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                        delay += delayAmount;
55976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen                        delayAmount *= 0.9;
560bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                    }
561bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                }
562bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            }
563bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
564bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    }
565bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
566bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    public void onDragOver(DragObject d) {
567bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        float[] r = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, d.dragView, null);
568bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mTargetCell = mContent.findNearestArea((int) r[0], (int) r[1], 1, 1, mTargetCell);
569bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
570bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (mTargetCell[0] != mPreviousTargetCell[0] || mTargetCell[1] != mPreviousTargetCell[1]) {
571bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mReorderAlarm.cancelAlarm();
572bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mReorderAlarm.setOnAlarmListener(mReorderAlarmListener);
573bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mReorderAlarm.setAlarm(150);
574bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mPreviousTargetCell[0] = mTargetCell[0];
575bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mPreviousTargetCell[1] = mTargetCell[1];
576bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
577df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
578df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
579bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    // This is used to compute the visual center of the dragView. The idea is that
580bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    // the visual center represents the user's interpretation of where the item is, and hence
581bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    // is the appropriate point to use when determining drop location.
582bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    private float[] getDragViewVisualCenter(int x, int y, int xOffset, int yOffset,
583bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            DragView dragView, float[] recycle) {
584bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        float res[];
585bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (recycle == null) {
586bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            res = new float[2];
587bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        } else {
588bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            res = recycle;
589df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        }
5902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
591bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // These represent the visual top and left of drag view if a dragRect was provided.
592bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // If a dragRect was not provided, then they correspond to the actual view left and
593bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // top, as the dragRect is in that case taken to be the entire dragView.
594bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // R.dimen.dragViewOffsetY.
595bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        int left = x - xOffset;
596bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        int top = y - yOffset;
597bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
598bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // In order to find the visual center, we shift by half the dragRect
599bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        res[0] = left + dragView.getDragRegion().width() / 2;
600bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        res[1] = top + dragView.getDragRegion().height() / 2;
601bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
602bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        return res;
603bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    }
604bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
605bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    OnAlarmListener mOnExitAlarmListener = new OnAlarmListener() {
606bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        public void onAlarm(Alarm alarm) {
607bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mLauncher.closeFolder(Folder.this);
608bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mCurrentDragInfo = null;
609bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mCurrentDragView = null;
610bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mSuppressOnAdd = false;
611bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mRearrangeOnClose = true;
612bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
613bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    };
6142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
615bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    public void onDragExit(DragObject d) {
616bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // We only close the folder if this is a true drag exit, ie. not because a drop
617bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // has occurred above the folder.
618bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (!d.dragComplete) {
619bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mOnExitAlarm.setOnAlarmListener(mOnExitAlarmListener);
620bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY);
621bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
622bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mReorderAlarm.cancelAlarm();
623bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mContent.onDragExit();
6242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
6252801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
626c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen    public void onDropCompleted(View target, DragObject d, boolean success) {
627bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mCurrentDragInfo = null;
628bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mCurrentDragView = null;
629bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mSuppressOnAdd = false;
63076078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen        if (!success) {
63176078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen            if (d.dragView != null) {
63276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen                if (target instanceof CellLayout) {
63376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen                    // TODO: we should animate the item back to the folder in this case
63476078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen                }
63576078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen            }
636bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            // TODO: if the drag fails, we need to re-add the item
63776078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen        }
638df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
639df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
640df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    public boolean isDropEnabled() {
641df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        return true;
642df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen    }
643df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen
644cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen    public DropTarget getDropTargetDelegate(DragObject d) {
645df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen        return null;
64631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
647a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen
6482801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private void setupContentDimension(int count) {
6492801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        ArrayList<View> list = getItemsInReadingOrder();
6502801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
6512801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int countX = mContent.getCountX();
6522801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int countY = mContent.getCountY();
6537c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        boolean done = false;
6547c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen
6557c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        while (!done) {
6567c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            int oldCountX = countX;
6577c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            int oldCountY = countY;
6587c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            if (countX * countY < count) {
6597c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                // Current grid is too small, expand it
6607c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                if (countX <= countY && countX < mMaxCountX) {
6617c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                    countX++;
6627c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                } else if (countY < mMaxCountY) {
6637c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                    countY++;
6647c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                }
6657c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                if (countY == 0) countY++;
6667c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            } else if ((countY - 1) * countX >= count && countY >= countX) {
6677c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                countY = Math.max(0, countY - 1);
6687c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            } else if ((countX - 1) * countY >= count) {
6697c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                countX = Math.max(0, countX - 1);
6702801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            }
6717c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            done = countX == oldCountX && countY == oldCountY;
6722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
6737c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        mContent.setGridSize(countX, countY);
6742801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        arrangeChildren(list);
6752801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
6762801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
6772801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    public boolean isFull() {
6782801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        return getItemCount() >= mMaxCountX * mMaxCountY;
6792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
6802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
6812801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private void centerAboutIcon() {
6822801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        CellLayout.LayoutParams iconLp = (CellLayout.LayoutParams) mFolderIcon.getLayoutParams();
6832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
6842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
6852801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
68676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        // Technically there is no padding at the bottom, but we add space equal to the padding
68776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        // and have to account for that here.
68876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen        int height = getPaddingTop() + mContent.getDesiredHeight() + mFolderNameHeight;
6892801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
6902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int centerX = iconLp.x + iconLp.width / 2;
6912801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int centerY = iconLp.y + iconLp.height / 2;
6922801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int centeredLeft = centerX - width / 2;
6932801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int centeredTop = centerY - height / 2;
6942801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
6952801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        CellLayoutChildren clc = (CellLayoutChildren) getParent();
6962801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int parentWidth = 0;
6972801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int parentHeight = 0;
6982801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (clc != null) {
6992801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            parentWidth = clc.getMeasuredWidth();
7002801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            parentHeight = clc.getMeasuredHeight();
7012801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
7022801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
7032801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int left = Math.min(Math.max(0, centeredLeft), parentWidth - width);
7042801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int top = Math.min(Math.max(0, centeredTop), parentHeight - height);
7052801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
7062801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int folderPivotX = width / 2 + (centeredLeft - left);
7072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int folderPivotY = height / 2 + (centeredTop - top);
7082801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        setPivotX(folderPivotX);
7092801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        setPivotY(folderPivotY);
7102801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int folderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() *
7112801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                (1.0f * folderPivotX / width));
7122801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int folderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() *
7132801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen                (1.0f * folderPivotY / height));
7142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mFolderIcon.setPivotX(folderIconPivotX);
7152801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mFolderIcon.setPivotY(folderIconPivotY);
7162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
7172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (mMode == PARTIAL_GROW) {
7182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.width = width;
7192801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.height = height;
7202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.x = left;
7212801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.y = top;
7222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        } else {
7232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            mNewSize.set(left, top, left + width, top + height);
7242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
7252801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
7262801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
7272801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private void setupContentForNumItems(int count) {
7282801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        setupContentDimension(count);
7292801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
7302801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
7312801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (lp == null) {
7322801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp = new CellLayout.LayoutParams(0, 0, -1, -1);
7332801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.isLockedToGrid = false;
7342801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            setLayoutParams(lp);
7352801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
7362801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        centerAboutIcon();
7372801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
7382801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
7392801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private void arrangeChildren(ArrayList<View> list) {
7402801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        int[] vacant = new int[2];
7412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (list == null) {
7422801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            list = getItemsInReadingOrder();
7432801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
7442801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        mContent.removeAllViews();
7452801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
7462801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        for (int i = 0; i < list.size(); i++) {
7472801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            View v = list.get(i);
7482801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            mContent.getVacantCell(vacant, 1, 1);
7492801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams();
7502801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.cellX = vacant[0];
7512801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            lp.cellY = vacant[1];
7522801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            ItemInfo info = (ItemInfo) v.getTag();
7532801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            info.cellX = vacant[0];
7542801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            info.cellY = vacant[1];
7552801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            boolean insert = false;
7562801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            mContent.addViewToCellLayout(v, insert ? 0 : -1, (int)info.id, lp, true);
7577c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            LauncherModel.addOrMoveItemInDatabase(mLauncher, info, mInfo.id, 0,
7587c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                    info.cellX, info.cellY);
7592801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
7607c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        mItemsInvalidated = true;
7612801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
7622801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
763a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen    public int getItemCount() {
764a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen        return mContent.getChildrenLayout().getChildCount();
765a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen    }
766a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen
767a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen    public View getItemAt(int index) {
768a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen        return mContent.getChildrenLayout().getChildAt(index);
769a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen    }
770a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen
7712801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    private void onCloseComplete() {
7722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (mRearrangeOnClose) {
7732801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            setupContentForNumItems(getItemCount());
7742801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            mRearrangeOnClose = false;
7752801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
7762801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen    }
7772801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen
778bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    public void onDrop(DragObject d) {
779bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        ShortcutInfo item;
780bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (d.dragInfo instanceof ApplicationInfo) {
781bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            // Came from all apps -- make a copy
782bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            item = ((ApplicationInfo) d.dragInfo).makeShortcut();
783bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            item.spanX = 1;
784bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            item.spanY = 1;
785bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        } else {
786bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            item = (ShortcutInfo) d.dragInfo;
787bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
788bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        // Dragged from self onto self
789bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (item == mCurrentDragInfo) {
790bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            ShortcutInfo si = (ShortcutInfo) mCurrentDragView.getTag();
791bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mCurrentDragView.getLayoutParams();
792bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            si.cellX = lp.cellX = mEmptyCell[0];
793bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            si.cellX = lp.cellY = mEmptyCell[1];
794bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mContent.addViewToCellLayout(mCurrentDragView, -1, (int)item.id, lp, true);
795bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mSuppressOnAdd = true;
796bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            mItemsInvalidated = true;
797bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            setupContentDimension(getItemCount());
798bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
799bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mInfo.add(item);
800bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    }
801bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
802bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    public void onAdd(ShortcutInfo item) {
803bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        mItemsInvalidated = true;
804bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (mSuppressOnAdd) return;
805bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (!findAndSetEmptyCells(item)) {
806bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            // The current layout is full, can we expand it?
807bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            setupContentForNumItems(getItemCount() + 1);
808bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen            findAndSetEmptyCells(item);
809bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        }
810bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        createAndAddShortcut(item);
811bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        LauncherModel.addOrMoveItemInDatabase(
812bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen                mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
813bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen    }
814bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen
815a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen    public void onRemove(ShortcutInfo item) {
8167c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        mItemsInvalidated = true;
817bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen        if (item == mCurrentDragInfo) return;
818a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen        View v = mContent.getChildAt(mDragItemPosition[0], mDragItemPosition[1]);
819a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen        mContent.removeView(v);
8202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        if (mState == STATE_ANIMATING) {
8212801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            mRearrangeOnClose = true;
8222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        } else {
8232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen            setupContentForNumItems(getItemCount());
8242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen        }
825a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen    }
8267c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen
82776078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen    public void onItemsChanged() {
82876078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen    }
82976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    public void onTitleChanged(CharSequence title) {
83076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen    }
83176078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen
8327c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen    public ArrayList<View> getItemsInReadingOrder() {
83376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen        return getItemsInReadingOrder(true);
83476078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen    }
83576078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen
83676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen    public ArrayList<View> getItemsInReadingOrder(boolean includeCurrentDragItem) {
8377c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        if (mItemsInvalidated) {
8387c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            mItemsInReadingOrder.clear();
8397c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            for (int j = 0; j < mContent.getCountY(); j++) {
8407c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                for (int i = 0; i < mContent.getCountX(); i++) {
8417c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                    View v = mContent.getChildAt(i, j);
8427c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                    if (v != null) {
84376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen                        ShortcutInfo info = (ShortcutInfo) v.getTag();
84476078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen                        if (info != mCurrentDragInfo || includeCurrentDragItem) {
84576078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen                            mItemsInReadingOrder.add(v);
84676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen                        }
8477c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                    }
8487c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen                }
8497c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            }
8507c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen            mItemsInvalidated = false;
8517c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        }
8527c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen        return mItemsInReadingOrder;
8537c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen    }
85431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
855