Folder.java revision b8c663c492d32963b6ee33750fc985f037c58f10
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 17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.Animator; 20df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.AnimatorListenerAdapter; 21c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohenimport android.animation.AnimatorSet; 22df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.ObjectAnimator; 23df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.PropertyValuesHolder; 24c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyalimport android.annotation.TargetApi; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.content.res.Resources; 27b745afbdd75157c73d581b345118cdaff99e912dWinson Chungimport android.graphics.Point; 28043f2af567178b82b0b41f12d379e7dd12da2936Winson Chungimport android.graphics.PointF; 29fb5411e98278d461b78aea0663d3e85f7a9e8a15Romain Guyimport android.graphics.Rect; 30c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyalimport android.os.Build; 317a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohenimport android.text.InputType; 32e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohenimport android.text.Selection; 33e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohenimport android.text.Spannable; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 353bf84d3250bf45f2a5b041245e9bd327e03e22c0Adam Cohenimport android.util.Log; 3676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.ActionMode; 3776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.KeyEvent; 38df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.view.LayoutInflater; 3976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.Menu; 4076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.MenuItem; 410c872ba544ecfd9b106bb66137da8680927590deAdam Cohenimport android.view.MotionEvent; 4231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View; 43c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyalimport android.view.ViewGroup; 443371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityEvent; 453371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohenimport android.view.accessibility.AccessibilityManager; 46c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohenimport android.view.animation.AccelerateInterpolator; 4776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.inputmethod.EditorInfo; 4876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.inputmethod.InputMethodManager; 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.LinearLayout; 50df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.widget.TextView; 514846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 52f406615354a92367481a60966b6b873cae37fe4cSunny Goyalimport com.android.launcher3.DragController.DragListener; 53325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerimport com.android.launcher3.FolderInfo.FolderListener; 54fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyalimport com.android.launcher3.UninstallDropTarget.UninstallSource; 55bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyalimport com.android.launcher3.Workspace.ItemOperator; 56091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 57edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 58c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList; 593bf84d3250bf45f2a5b041245e9bd327e03e22c0Adam Cohenimport java.util.Collections; 60c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 6131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Represents a set of icons chosen by the user or generated by the system. 6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 648dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohenpublic class Folder extends LinearLayout implements DragSource, View.OnClickListener, 65ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener, 66fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal View.OnFocusChangeListener, DragListener, UninstallSource { 674eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen private static final String TAG = "Launcher.Folder"; 68df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 69c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 70c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * We avoid measuring {@link #mContentWrapper} with a 0 width or height, as this 71c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * results in CellLayout being measured as UNSPECIFIED, which it does not support. 72c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 73c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static final int MIN_CONTENT_DIMEN = 5; 7431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 75df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_NONE = -1; 76df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_SMALL = 0; 77df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_ANIMATING = 1; 78df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_OPEN = 2; 79df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Time for which the scroll hint is shown before automatically changing page. 824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public static final int SCROLL_HINT_DURATION = DragController.SCROLL_DELAY; 844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 865d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal * Time in milliseconds for which an icon sticks to the target position 875d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal * in case of a sorted folder. 885d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal */ 895d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal private static final int SORTED_STICKY_REORDER_DELAY = 1500; 905d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 915d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal /** 924846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Fraction of icon width which behave as scroll region. 934846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 944846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private static final float ICON_OVERSCROLL_WIDTH_FACTOR = 0.45f; 954846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 96f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private static final int REORDER_DELAY = 250; 975d518fa77c56a65104f02f40269ad8e43f3431b2Adam Cohen private static final int ON_EXIT_CLOSE_DELAY = 400; 98c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static final Rect sTempRect = new Rect(); 99c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 100c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static String sDefaultFolderName; 101c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static String sHintText; 102c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 103c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final Alarm mReorderAlarm = new Alarm(); 104c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final Alarm mOnExitAlarm = new Alarm(); 105b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal private final Alarm mOnScrollHintAlarm = new Alarm(); 106b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal @Thunk final Alarm mScrollPauseAlarm = new Alarm(); 107c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 108091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>(); 109c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 110c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mExpandDuration; 111c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mMaterialExpandDuration; 112c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mMaterialExpandStagger; 113c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 114c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final InputMethodManager mInputMethodManager; 115c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 116c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected final Launcher mLauncher; 117c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected DragController mDragController; 118c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected FolderInfo mInfo; 119c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 120091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk FolderIcon mFolderIcon; 121c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 122b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal @Thunk FolderPagedView mContent; 123091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk View mContentWrapper; 124c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal FolderEditText mFolderName; 125c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 126290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private View mFooter; 127290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private int mFooterHeight; 128c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 129c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // Cell ranks used for drag and drop 130091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mTargetRank, mPrevTargetRank, mEmptyCellRank; 131c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 132091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mState = STATE_NONE; 133c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private boolean mRearrangeOnClose = false; 1347c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen boolean mItemsInvalidated = false; 135bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private ShortcutInfo mCurrentDragInfo; 136bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private View mCurrentDragView; 13755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi private boolean mIsExternalDrag; 138bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen boolean mSuppressOnAdd = false; 13967bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mDragInProgress = false; 14067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mDeleteFolderOnDropCompleted = false; 14167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mSuppressFolderDeletion = false; 14205e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen private boolean mItemAddedBackToSelfViaIcon = false; 143091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk float mFolderIconPivotX; 144091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk float mFolderIconPivotY; 14576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean mIsEditingName = false; 1461960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen 147fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen private boolean mDestroyed; 148fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 149091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Runnable mDeferredAction; 1501e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka private boolean mDeferDropAfterUninstall; 1511e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka private boolean mUninstallSuccessful; 1521e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 1534846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Folder scrolling 1544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int mScrollAreaOffset; 1554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 156091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mScrollHintDir = DragController.SCROLL_NONE; 157091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mCurrentScrollDir = DragController.SCROLL_NONE; 1584846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 163c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * @param attrs The attributes set containing the Workspace's customization values. 16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Folder(Context context, AttributeSet attrs) { 16631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setAlwaysDrawnWithCacheEnabled(false); 16876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager = (InputMethodManager) 1698b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 17076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 171c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal Resources res = getResources(); 172c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mExpandDuration = res.getInteger(R.integer.config_folderExpandDuration); 173c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mMaterialExpandDuration = res.getInteger(R.integer.config_materialFolderExpandDuration); 174c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mMaterialExpandStagger = res.getInteger(R.integer.config_materialFolderExpandStagger); 1754ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 1764ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen if (sDefaultFolderName == null) { 1774ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen sDefaultFolderName = res.getString(R.string.folder_name); 1784ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 179a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen if (sHintText == null) { 180a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen sHintText = res.getString(R.string.folder_hint_text); 181a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen } 1824eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen mLauncher = (Launcher) context; 183ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // We need this view to be focusable in touch mode so that when text editing of the folder 184ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // name is complete, we have something to focus on, thus hiding the cursor and giving 185c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // reliable behavior when clicking the text field (since it will always gain focus on click). 186ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen setFocusableInTouchMode(true); 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 19031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected void onFinishInflate() { 19131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.onFinishInflate(); 192c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContentWrapper = findViewById(R.id.folder_content_wrapper); 193b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent = (FolderPagedView) findViewById(R.id.folder_content); 194c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.setFolder(this); 195dcbcc86353e9ed52daac87f292aece667cd0ac71Sunny Goyal 196ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName = (FolderEditText) findViewById(R.id.folder_name); 197ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setFolder(this); 198ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen mFolderName.setOnFocusChangeListener(this); 19976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 20076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen // We disable action mode for now since it messes up the view on phones 20176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback); 20276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setOnEditorActionListener(this); 2034ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setSelectAllOnFocus(true); 2047a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen mFolderName.setInputType(mFolderName.getInputType() | 2057a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS); 206c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 207b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mFooter = findViewById(R.id.folder_footer); 208b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal updateFooterHeight(); 209b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal } 210b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal 211b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal public void updateFooterHeight() { 212290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // We find out how tall footer wants to be (it is set to wrap_content), so that 213c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // we can allocate the appropriate amount of space for it. 214c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int measureSpec = MeasureSpec.UNSPECIFIED; 215290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.measure(measureSpec, measureSpec); 216290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooterHeight = mFooter.getMeasuredHeight(); 21731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 21976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { 22076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 22176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 22276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 22376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 22476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onCreateActionMode(ActionMode mode, Menu menu) { 22576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 22676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 22776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 22876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onDestroyActionMode(ActionMode mode) { 22976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 23076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 23176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 23276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 23376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 23476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen }; 23576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onClick(View v) { 237df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 238df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 239b5fe60c8a502fb7e265e3183550478b2b2a49264Adam Cohen mLauncher.onClick(v); 240df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 24131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 24231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 24331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onLongClick(View v) { 24436a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung // Return if global dragging is not enabled 24536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung if (!mLauncher.isDraggingEnabled()) return true; 24636a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 247df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 248df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 249df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ShortcutInfo item = (ShortcutInfo) tag; 250df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (!v.isInTouchMode()) { 251df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return false; 252df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 253df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 254b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher.getWorkspace().beginDragShared(v, new Point(), this, false); 25576078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 25676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen mCurrentDragInfo = item; 257c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mEmptyCellRank = item.rank; 258bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = v; 259fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 260290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mContent.removeItem(mCurrentDragView); 261fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mInfo.remove(mCurrentDragInfo); 26267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDragInProgress = true; 26305e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = false; 264df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 26531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean isEditingName() { 26976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mIsEditingName; 27076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 27176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 27276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void startEditingFolderName() { 273a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(""); 27476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = true; 27576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 27676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 27776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void dismissEditingName() { 27876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 27976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen doneEditingFolderName(true); 28076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 28176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 28276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void doneEditingFolderName(boolean commit) { 283a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(sHintText); 2841df26a368a135395b7bd61e9b109044b33b1b0beAdam Cohen // Convert to a string here to ensure that no other state associated with the text field 2851df26a368a135395b7bd61e9b109044b33b1b0beAdam Cohen // gets saved. 2863371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen String newTitle = mFolderName.getText().toString(); 2873371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mInfo.setTitle(newTitle); 28876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen LauncherModel.updateItemInDatabase(mLauncher, mInfo); 289ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 2903371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (commit) { 2913371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 2928b805b17158886035b38261eb611d8641701ae43Michael Jurka String.format(getContext().getString(R.string.folder_renamed), newTitle)); 2933371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 294ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // In order to clear the focus from the text field, we set the focus on ourself. This 295ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // ensures that every time the field is clicked, focus is gained, giving reliable behavior. 296ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen requestFocus(); 297ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 298e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohen Selection.setSelection((Spannable) mFolderName.getText(), 0, 0); 29976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = false; 30076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 30176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 30276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 30376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (actionId == EditorInfo.IME_ACTION_DONE) { 30476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen dismissEditingName(); 30576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 30676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 30776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 30876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 30976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 31076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public View getEditTextRegion() { 31176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mFolderName; 31276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 31376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 3140c872ba544ecfd9b106bb66137da8680927590deAdam Cohen /** 3150c872ba544ecfd9b106bb66137da8680927590deAdam Cohen * We need to handle touch events to prevent them from falling through to the workspace below. 3160c872ba544ecfd9b106bb66137da8680927590deAdam Cohen */ 3170c872ba544ecfd9b106bb66137da8680927590deAdam Cohen @Override 3180c872ba544ecfd9b106bb66137da8680927590deAdam Cohen public boolean onTouchEvent(MotionEvent ev) { 3190c872ba544ecfd9b106bb66137da8680927590deAdam Cohen return true; 3200c872ba544ecfd9b106bb66137da8680927590deAdam Cohen } 3210c872ba544ecfd9b106bb66137da8680927590deAdam Cohen 32200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragController(DragController dragController) { 32300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = dragController; 32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 326c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void setFolderIcon(FolderIcon icon) { 3272801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mFolderIcon = icon; 3282801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 3292801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 3303371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 3313371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 3323371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // When the folder gets focus, we don't want to announce the list of items. 3333371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 3343371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3353371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 33631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return the FolderInfo object associated with this folder 33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 33931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FolderInfo getInfo() { 34031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mInfo; 34131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 34231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void bind(FolderInfo info) { 34431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mInfo = info; 345df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ArrayList<ShortcutInfo> children = info.contents; 34608f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal Collections.sort(children, Utilities.RANK_COMPARATOR); 347c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 348c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal ArrayList<ShortcutInfo> overflow = mContent.bindItems(children); 3490057bbcfa4a2ee12c5e87cba8c3fac8eadb078edAdam Cohen 3504ff73887f28b831e8da38f2c417d55350ad88956Jason Monk // If our folder has too many items we prune them from the list. This is an issue 351c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // when upgrading from the old Folders implementation which could contain an unlimited 352c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // number of items. 353c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen for (ShortcutInfo item: overflow) { 354c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen mInfo.remove(item); 355c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, item); 356c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen } 357c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 358c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 359c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal if (lp == null) { 360c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal lp = new DragLayer.LayoutParams(0, 0); 361c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal lp.customPosition = true; 362c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal setLayoutParams(lp); 363c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 364c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal centerAboutIcon(); 365c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 3664dbe6d993485a702505ee4895db94aaa89655f2cAdam Cohen mItemsInvalidated = true; 367ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen updateTextViewFocus(); 368a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen mInfo.addListener(this); 3694ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 370afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (!sDefaultFolderName.contentEquals(mInfo.title)) { 3714ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(mInfo.title); 3724ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } else { 3734ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(""); 3744ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 37533231f587e1a6f716af68e6198df774d2847a8e5Winson Chung 37633231f587e1a6f716af68e6198df774d2847a8e5Winson Chung // In case any children didn't come across during loading, clean up the folder accordingly 37733231f587e1a6f716af68e6198df774d2847a8e5Winson Chung mFolderIcon.post(new Runnable() { 37833231f587e1a6f716af68e6198df774d2847a8e5Winson Chung public void run() { 37933231f587e1a6f716af68e6198df774d2847a8e5Winson Chung if (getItemCount() <= 1) { 38033231f587e1a6f716af68e6198df774d2847a8e5Winson Chung replaceFolderWithFinalItem(); 38133231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } 38233231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } 38333231f587e1a6f716af68e6198df774d2847a8e5Winson Chung }); 384df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 385df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 386df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 387df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Creates a new UserFolder, inflated from R.layout.user_folder. 388df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 389df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @param context The application's context. 390df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 391df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @return A new UserFolder. 392df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 393df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static Folder fromXml(Context context) { 394b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null); 395df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 396df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 397df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 398df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * This method is intended to make the UserFolder to be visually identical in size and position 399df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * to its associated FolderIcon. This allows for a seamless transition into the expanded state. 400df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 401df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private void positionAndSizeAsIcon() { 4023e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (!(getParent() instanceof DragLayer)) return; 403662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setScaleX(0.8f); 404662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setScaleY(0.8f); 405662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setAlpha(0f); 406df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_SMALL; 407df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 408df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 409c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen private void prepareReveal() { 410c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setScaleX(1f); 411c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setScaleY(1f); 412c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setAlpha(1f); 413c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mState = STATE_SMALL; 414c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 4153e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 416c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void animateOpen() { 4178e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 418c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 419b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.completePendingPageChanges(); 420b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (!(mDragInProgress && mContent.mIsSorted)) { 421b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Open on the first page. 422b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.snapToPageImmediately(0); 4234846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4244846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 425c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator openFolderAnim = null; 426c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen final Runnable onCompleteRunnable; 427d794a3f46521b972fa02826d379d1efa112793d2Kenny Guy if (!Utilities.isLmpOrAbove()) { 428c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen positionAndSizeAsIcon(); 429c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen centerAboutIcon(); 430c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 431c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1); 432c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f); 433c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f); 434c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen final ObjectAnimator oa = 435c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 436c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen oa.setDuration(mExpandDuration); 437c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim = oa; 438c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 439c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setLayerType(LAYER_TYPE_HARDWARE, null); 440c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable = new Runnable() { 441c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen @Override 442c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void run() { 443c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setLayerType(LAYER_TYPE_NONE, null); 444c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 445c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen }; 446c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } else { 447c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen prepareReveal(); 448c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen centerAboutIcon(); 449c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 450c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 451c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int height = getFolderHeight(); 452c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 453c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float transX = - 0.075f * (width / 2 - getPivotX()); 454c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float transY = - 0.075f * (height / 2 - getPivotY()); 455c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setTranslationX(transX); 456c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setTranslationY(transY); 457c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder tx = PropertyValuesHolder.ofFloat("translationX", transX, 0); 458c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder ty = PropertyValuesHolder.ofFloat("translationY", transY, 0); 459c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 460c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX()); 461c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY()); 462c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float radius = (float) Math.sqrt(rx * rx + ry * ry); 463c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); 464c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator reveal = LauncherAnimUtils.createCircularReveal(this, (int) getPivotX(), 465c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen (int) getPivotY(), 0, radius); 466c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen reveal.setDuration(mMaterialExpandDuration); 467c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 468c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 469bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setAlpha(0f); 470bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal Animator iconsAlpha = LauncherAnimUtils.ofFloat(mContentWrapper, "alpha", 0f, 1f); 471c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setDuration(mMaterialExpandDuration); 472c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setStartDelay(mMaterialExpandStagger); 473c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 474c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 475290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.setAlpha(0f); 476290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal Animator textAlpha = LauncherAnimUtils.ofFloat(mFooter, "alpha", 0f, 1f); 477c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setDuration(mMaterialExpandDuration); 478c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setStartDelay(mMaterialExpandStagger); 479c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 480c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 481c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator drift = LauncherAnimUtils.ofPropertyValuesHolder(this, tx, ty); 482c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setDuration(mMaterialExpandDuration); 483c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setStartDelay(mMaterialExpandStagger); 484c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setInterpolator(new LogDecelerateInterpolator(60, 0)); 485c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 486c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(drift); 487c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(iconsAlpha); 488c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(textAlpha); 489c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(reveal); 490c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 491c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim = anim; 492c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 493bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setLayerType(LAYER_TYPE_HARDWARE, null); 494c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable = new Runnable() { 495c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen @Override 496c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void run() { 497bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setLayerType(LAYER_TYPE_NONE, null); 498c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 499c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen }; 500c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 501c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim.addListener(new AnimatorListenerAdapter() { 502df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 503df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 5043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 505bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.getAccessibilityDescription()); 506df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 507df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 508df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 509df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 5102801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_OPEN; 511c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 512c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen if (onCompleteRunnable != null) { 513c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable.run(); 514c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 51555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 516bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.setFocusOnFirstChild(); 517df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 518df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 519c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim.start(); 52055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 52155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Make sure the folder picks up the last drag move even if the finger doesn't move. 52255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mDragController.isDragging()) { 52355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mDragController.forceTouchMove(); 52455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 52534b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 526b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal FolderPagedView pages = (FolderPagedView) mContent; 527b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal pages.verifyVisibleHighResIcons(pages.getNextPage()); 52855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 52955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 53055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void beginExternalDrag(ShortcutInfo item) { 53155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mCurrentDragInfo = item; 5325d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mEmptyCellRank = mContent.allocateRankForNewItem(item); 53355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mIsExternalDrag = true; 53455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mDragInProgress = true; 535b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal 536b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (mContent.mIsSorted) { 5375d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.setOnAlarmListener(null); 5385d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.cancelAlarm(); 5395d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.setAlarm(SORTED_STICKY_REORDER_DELAY); 5405d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal } 5415d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 542f406615354a92367481a60966b6b873cae37fe4cSunny Goyal // Since this folder opened by another controller, it might not get onDrop or 543f406615354a92367481a60966b6b873cae37fe4cSunny Goyal // onDropComplete. Perform cleanup once drag-n-drop ends. 544f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mDragController.addDragListener(this); 545f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } 546f406615354a92367481a60966b6b873cae37fe4cSunny Goyal 547f406615354a92367481a60966b6b873cae37fe4cSunny Goyal @Override 548f406615354a92367481a60966b6b873cae37fe4cSunny Goyal public void onDragStart(DragSource source, Object info, int dragAction) { } 549f406615354a92367481a60966b6b873cae37fe4cSunny Goyal 550f406615354a92367481a60966b6b873cae37fe4cSunny Goyal @Override 551f406615354a92367481a60966b6b873cae37fe4cSunny Goyal public void onDragEnd() { 552f406615354a92367481a60966b6b873cae37fe4cSunny Goyal if (mIsExternalDrag && mDragInProgress) { 553f406615354a92367481a60966b6b873cae37fe4cSunny Goyal completeDragExit(); 554f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } 555f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mDragController.removeDragListener(this); 556df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 557df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 558091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void sendCustomAccessibilityEvent(int type, String text) { 5598b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 5608b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 5618b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isEnabled()) { 5623371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent event = AccessibilityEvent.obtain(type); 5633371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen onInitializeAccessibilityEvent(event); 5643371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen event.getText().add(text); 5658b805b17158886035b38261eb611d8641701ae43Michael Jurka accessibilityManager.sendAccessibilityEvent(event); 5663371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 5673371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 5683371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 569df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void animateClosed() { 5708e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 571662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0); 572662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f); 573662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f); 574032e6bad1ba588ed8a884fb8f28fb8596efac480Michael Jurka final ObjectAnimator oa = 5752ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 576df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 5772801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.addListener(new AnimatorListenerAdapter() { 578df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 579df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 5802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen onCloseComplete(); 5810121c3ea3d5bae176af193ea8ef23ae8a868dd31Michael Jurka setLayerType(LAYER_TYPE_NONE, null); 5822801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_SMALL; 583df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 584df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 585df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 5863371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 5878b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getString(R.string.folder_closed)); 588df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 589df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 590df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 5912801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.setDuration(mExpandDuration); 5920121c3ea3d5bae176af193ea8ef23ae8a868dd31Michael Jurka setLayerType(LAYER_TYPE_HARDWARE, null); 593f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka oa.start(); 594df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 595df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 596cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public boolean acceptDrop(DragObject d) { 597cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen final ItemInfo item = (ItemInfo) d.dragInfo; 598df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen final int itemType = item.itemType; 5992801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || 6002801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && 6012801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen !isFull()); 602df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 603df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 604cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDragEnter(DragObject d) { 605c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mPrevTargetRank = -1; 606bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.cancelAlarm(); 607b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Get the area offset such that the folder only closes if half the drag icon width 608b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // is outside the folder area 609b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollAreaOffset = d.dragView.getDragRegionWidth() / 2 - d.xOffset; 610df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 611df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 612bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mReorderAlarmListener = new OnAlarmListener() { 613bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 614c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.realTimeReorder(mEmptyCellRank, mTargetRank); 615c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mEmptyCellRank = mTargetRank; 616bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 617bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 618bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 619c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 6202374abfda3e53f84e005df8923170308e4df8c03Adam Cohen public boolean isLayoutRtl() { 6212374abfda3e53f84e005df8923170308e4df8c03Adam Cohen return (getLayoutDirection() == LAYOUT_DIRECTION_RTL); 6222374abfda3e53f84e005df8923170308e4df8c03Adam Cohen } 6232374abfda3e53f84e005df8923170308e4df8c03Adam Cohen 6244846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 625bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragOver(DragObject d) { 6264846193300245c8c0a1f9bde3175f273df044309Sunny Goyal onDragOver(d, REORDER_DELAY); 6274846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6284846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6294846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int getTargetRank(DragObject d, float[] recycle) { 6304846193300245c8c0a1f9bde3175f273df044309Sunny Goyal recycle = d.getVisualCenter(recycle); 6314846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return mContent.findNearestArea( 6324846193300245c8c0a1f9bde3175f273df044309Sunny Goyal (int) recycle[0] - getPaddingLeft(), (int) recycle[1] - getPaddingTop()); 6334846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6344846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 635091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void onDragOver(DragObject d, int reorderDelay) { 636b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (mScrollPauseAlarm.alarmPending()) { 6374846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return; 6384846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6394846193300245c8c0a1f9bde3175f273df044309Sunny Goyal final float[] r = new float[2]; 6404846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mTargetRank = getTargetRank(d, r); 641f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 642c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal if (mTargetRank != mPrevTargetRank) { 6434cda5b770db7f375a4766fe6c0d657b9d5303374Alan Viverette mReorderAlarm.cancelAlarm(); 644c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal mReorderAlarm.setOnAlarmListener(mReorderAlarmListener); 645c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal mReorderAlarm.setAlarm(REORDER_DELAY); 646c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mPrevTargetRank = mTargetRank; 647bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 6484846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6494846193300245c8c0a1f9bde3175f273df044309Sunny Goyal float x = r[0]; 650b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal int currentPage = mContent.getNextPage(); 6514846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 652b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal float cellOverlap = mContent.getCurrentCellLayout().getCellWidth() 6533b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal * ICON_OVERSCROLL_WIDTH_FACTOR; 6543b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal boolean isOutsideLeftEdge = x < cellOverlap; 6553b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal boolean isOutsideRightEdge = x > (getWidth() - cellOverlap); 6564846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 657b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (currentPage > 0 && (mContent.rtlLayout ? isOutsideRightEdge : isOutsideLeftEdge)) { 6583b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal showScrollHint(DragController.SCROLL_LEFT, d); 659b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal } else if (currentPage < (mContent.getPageCount() - 1) 660b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal && (mContent.rtlLayout ? isOutsideLeftEdge : isOutsideRightEdge)) { 6613b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal showScrollHint(DragController.SCROLL_RIGHT, d); 6624846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else { 6634846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.cancelAlarm(); 6644846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mScrollHintDir != DragController.SCROLL_NONE) { 665b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.clearScrollHint(); 6664846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 6674846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6684846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 669df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 670df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 6713b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal private void showScrollHint(int direction, DragObject d) { 6723b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal // Show scroll hint on the right 6733b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal if (mScrollHintDir != direction) { 674b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.showScrollHint(direction); 6753b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mScrollHintDir = direction; 6763b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal } 6773b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 6783b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal // Set alarm for when the hint is complete 6793b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal if (!mOnScrollHintAlarm.alarmPending() || mCurrentScrollDir != direction) { 6803b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mCurrentScrollDir = direction; 6813b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mOnScrollHintAlarm.cancelAlarm(); 6823b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mOnScrollHintAlarm.setOnAlarmListener(new OnScrollHintListener(d)); 6833b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mOnScrollHintAlarm.setAlarm(SCROLL_HINT_DURATION); 6843b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 6853b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mReorderAlarm.cancelAlarm(); 6863b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mTargetRank = mEmptyCellRank; 6873b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal } 6883b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal } 6893b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 690bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mOnExitAlarmListener = new OnAlarmListener() { 691bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 6923e8f811f31a2275e778244427271f77f4116c08bAdam Cohen completeDragExit(); 693bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 694bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 6952801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 69695bb800de9b0142bea0110b074eddbcf0e475736Adam Cohen public void completeDragExit() { 697f406615354a92367481a60966b6b873cae37fe4cSunny Goyal if (mInfo.opened) { 698f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mLauncher.closeFolder(); 699f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mRearrangeOnClose = true; 700f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } else { 701f406615354a92367481a60966b6b873cae37fe4cSunny Goyal rearrangeChildren(); 702f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } 7033e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragInfo = null; 7043e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragView = null; 7053e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mSuppressOnAdd = false; 70655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mIsExternalDrag = false; 7073e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 7083e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 709bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragExit(DragObject d) { 71053b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini // We only close the folder if this is a true drag exit, ie. not because 71153b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini // a drop has occurred above the folder. 712bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (!d.dragComplete) { 713bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setOnAlarmListener(mOnExitAlarmListener); 714bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY); 715bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 716bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mReorderAlarm.cancelAlarm(); 7174846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 718b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mOnScrollHintAlarm.cancelAlarm(); 719b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollPauseAlarm.cancelAlarm(); 720b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (mScrollHintDir != DragController.SCROLL_NONE) { 721b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.clearScrollHint(); 722b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 7234846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 7242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7252801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7261e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void onDropCompleted(final View target, final DragObject d, 7271e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka final boolean isFlingToDelete, final boolean success) { 7281e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (mDeferDropAfterUninstall) { 729f3007589e346df224d357b389069adfeb266545eMichael Jurka Log.d(TAG, "Deferred handling drop because waiting for uninstall."); 7301e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction = new Runnable() { 7311e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void run() { 7321e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka onDropCompleted(target, d, isFlingToDelete, success); 7331e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction = null; 7341e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7351e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka }; 7361e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka return; 7371e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7381e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 7391e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka boolean beingCalledAfterUninstall = mDeferredAction != null; 7401e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka boolean successfulDrop = 7411e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka success && (!beingCalledAfterUninstall || mUninstallSuccessful); 7425f8afe6280eae34620067696173e71943e1a30a3Winson Chung 7431e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (successfulDrop) { 74455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mDeleteFolderOnDropCompleted && !mItemAddedBackToSelfViaIcon && target != this) { 74567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen replaceFolderWithFinalItem(); 74667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 74767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } else { 74867bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen // The drag failed, we need to return the item to the folder 749b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal ShortcutInfo info = (ShortcutInfo) d.dragInfo; 750b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal View icon = (mCurrentDragView != null && mCurrentDragView.getTag() == info) 751b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal ? mCurrentDragView : mContent.createNewView(info); 752b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal ArrayList<View> views = getItemsInReadingOrder(); 753b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal views.add(info.rank, icon); 754b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mContent.arrangeChildren(views, views.size()); 755b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mItemsInvalidated = true; 756b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal 757b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mSuppressOnAdd = true; 75867bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mFolderIcon.onDrop(d); 759b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mSuppressOnAdd = false; 76067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 76167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen 76267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (target != this) { 76367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (mOnExitAlarm.alarmPending()) { 76467bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mOnExitAlarm.cancelAlarm(); 7655455425c1b0355f5dd652cc8e7a2369c33dc9883Michael Jurka if (!successfulDrop) { 7667a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen mSuppressFolderDeletion = true; 7677a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 7685d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.cancelAlarm(); 76967bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen completeDragExit(); 77067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 7719c58d8269b3bdfdbe500b52ccce878ff2edb196bAdam Cohen } 7729c58d8269b3bdfdbe500b52ccce878ff2edb196bAdam Cohen 77367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDeleteFolderOnDropCompleted = false; 77467bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDragInProgress = false; 77505e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = false; 776bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragInfo = null; 777bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = null; 778bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mSuppressOnAdd = false; 7794045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen 7804045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen // Reordering may have occured, and we need to save the new item locations. We do this once 7814045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen // at the end to prevent unnecessary database operations. 782f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemLocationsInDatabaseBatch(); 7834045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen } 7844045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen 785fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal @Override 7861e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void deferCompleteDropAfterUninstallActivity() { 7871e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferDropAfterUninstall = true; 7881e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7891e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 790fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal @Override 7911e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void onUninstallActivityReturned(boolean success) { 7921e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferDropAfterUninstall = false; 7931e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mUninstallSuccessful = success; 7941e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (mDeferredAction != null) { 7951e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction.run(); 7961e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7971e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7981e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 799a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 800eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public float getIntrinsicIconScaleFactor() { 801eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung return 1f; 802eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 803eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 804eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung @Override 805043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public boolean supportsFlingToDelete() { 806043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung return true; 807043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 808043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 8091eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood @Override 8101eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood public boolean supportsAppInfoDropTarget() { 8111eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood return false; 8121eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood } 8131eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood 8141eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood @Override 8151eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood public boolean supportsDeleteDropTarget() { 8161eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood return true; 8171eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood } 8181eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood 819a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onFlingToDelete(DragObject d, int x, int y, PointF vec) { 820a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // Do nothing 821a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 822a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 823a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 824a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onFlingToDeleteCompleted() { 825a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // Do nothing 826a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 827a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 828f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private void updateItemLocationsInDatabaseBatch() { 829f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<View> list = getItemsInReadingOrder(); 830f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 831f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < list.size(); i++) { 832f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen View v = list.get(i); 833f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo info = (ItemInfo) v.getTag(); 83408f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal info.rank = i; 835f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen items.add(info); 836f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 837f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 838f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen LauncherModel.moveItemsInDatabase(mLauncher, items, mInfo.id, 0); 839f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 840f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 841e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen public void addItemLocationsInDatabase() { 842e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen ArrayList<View> list = getItemsInReadingOrder(); 843e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen for (int i = 0; i < list.size(); i++) { 844e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen View v = list.get(i); 845e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen ItemInfo info = (ItemInfo) v.getTag(); 846e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen LauncherModel.addItemToDatabase(mLauncher, info, mInfo.id, 0, 8471d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal info.cellX, info.cellY); 848e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 849e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 850e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 85167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen public void notifyDrop() { 85267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (mDragInProgress) { 85305e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = true; 85476078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 855df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 856df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 857df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public boolean isDropEnabled() { 858df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return true; 859df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 860df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 8612801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen public boolean isFull() { 862c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return mContent.isFull(); 8632801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 8642801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 8652801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void centerAboutIcon() { 8668e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 8672801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 868892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer); 8692801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 870f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int height = getFolderHeight(); 8718e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen 872c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect); 8732801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 874af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 875af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 876af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung 877c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int centerX = (int) (sTempRect.left + sTempRect.width() * scale / 2); 878c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int centerY = (int) (sTempRect.top + sTempRect.height() * scale / 2); 8792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredLeft = centerX - width / 2; 8802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredTop = centerY - height / 2; 8813057b1c259dafc555ff1eec32a9d2f7f81bb0bdaWinson Chung int currentPage = mLauncher.getWorkspace().getNextPage(); 8827cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // In case the workspace is scrolling, we need to use the final scroll to compute 8837cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // the folders bounds. 8847cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen mLauncher.getWorkspace().setFinalScrollForPageChange(currentPage); 88535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We first fetch the currently visible CellLayoutChildren 8867cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage); 887a52570f8f9ad65b85e33a2f2e87722f9edd6c6f4Michael Jurka ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets(); 88835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen Rect bounds = new Rect(); 88935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen parent.getDescendantRectRelativeToSelf(boundingLayout, bounds); 8907cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // We reset the workspaces scroll 8917cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen mLauncher.getWorkspace().resetFinalScrollForPageChange(currentPage); 89235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 89335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We need to bound the folder to the currently visible CellLayoutChildren 89435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int left = Math.min(Math.max(bounds.left, centeredLeft), 89535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.left + bounds.width() - width); 89635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int top = Math.min(Math.max(bounds.top, centeredTop), 89735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.top + bounds.height() - height); 898af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung if (grid.isPhone() && (grid.availableWidthPx - width) < grid.iconSizePx) { 899af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung // Center the folder if it is full (on phones only) 900af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung left = (grid.availableWidthPx - width) / 2; 901af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung } else if (width >= bounds.width()) { 902af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung // If the folder doesn't fit within the bounds, center it about the desired bounds 90335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen left = bounds.left + (bounds.width() - width) / 2; 90435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 90535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen if (height >= bounds.height()) { 90635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen top = bounds.top + (bounds.height() - height) / 2; 9070e4857c302da6adbd45231d7a8bae0289fa33250Adam Cohen } 9082801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 9092801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotX = width / 2 + (centeredLeft - left); 9102801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotY = height / 2 + (centeredTop - top); 9112801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotX(folderPivotX); 9122801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotY(folderPivotY); 913268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * 9142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotX / width)); 915268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * 9162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotY / height)); 9173bf84d3250bf45f2a5b041245e9bd327e03e22c0Adam Cohen 918662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.width = width; 919662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.height = height; 920662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.x = left; 921662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.y = top; 9222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 9232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 924268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen float getPivotXForIconAnimation() { 925268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen return mFolderIconPivotX; 926268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen } 927268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen float getPivotYForIconAnimation() { 928268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen return mFolderIconPivotY; 929268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen } 930268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen 931892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung private int getContentAreaHeight() { 932892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 933892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 934892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung Rect workspacePadding = grid.getWorkspacePadding(grid.isLandscape ? 935892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung CellLayout.LANDSCAPE : CellLayout.PORTRAIT); 936892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung int maxContentAreaHeight = grid.availableHeightPx - 937892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung workspacePadding.top - workspacePadding.bottom - 938290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooterHeight; 9391960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen int height = Math.min(maxContentAreaHeight, 940892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung mContent.getDesiredHeight()); 9411960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen return Math.max(height, MIN_CONTENT_DIMEN); 9421960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen } 9431960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen 9441960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen private int getContentAreaWidth() { 9451960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen return Math.max(mContent.getDesiredWidth(), MIN_CONTENT_DIMEN); 946892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung } 947892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 948f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private int getFolderHeight() { 949c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return getFolderHeight(getContentAreaHeight()); 950c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 951c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 952c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private int getFolderHeight(int contentAreaHeight) { 953290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return getPaddingTop() + getPaddingBottom() + contentAreaHeight + mFooterHeight; 954f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 955f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 956f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 957c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentWidth = getContentAreaWidth(); 958c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentHeight = getContentAreaHeight(); 9592801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 960c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(contentWidth, MeasureSpec.EXACTLY); 961c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY); 962c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 963c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.setFixedSize(contentWidth, contentHeight); 964c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContentWrapper.measure(contentAreaWidthSpec, contentAreaHeightSpec); 965290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.measure(contentAreaWidthSpec, 966290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal MeasureSpec.makeMeasureSpec(mFooterHeight, MeasureSpec.EXACTLY)); 967c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 968c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int folderWidth = getPaddingLeft() + getPaddingRight() + contentWidth; 969c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int folderHeight = getFolderHeight(contentHeight); 970c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal setMeasuredDimension(folderWidth, folderHeight); 971c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 972c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 973c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 974c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * Rearranges the children based on their rank. 975c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 976c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void rearrangeChildren() { 977c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(-1); 978c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 979c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 980c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 981c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * Rearranges the children based on their rank. 982c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * @param itemCount if greater than the total children count, empty spaces are left at the end, 983c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * otherwise it is ignored. 984c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 985c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void rearrangeChildren(int itemCount) { 986c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal ArrayList<View> views = getItemsInReadingOrder(); 987c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.arrangeChildren(views, Math.max(itemCount, views.size())); 9887c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 9892801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 9902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 991c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal // TODO remove this once GSA code fix is submitted 992c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal public ViewGroup getContent() { 993c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal return (ViewGroup) mContent; 994c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal } 995c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal 996a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public int getItemCount() { 997c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return mContent.getItemCount(); 998a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 999a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 1000091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void onCloseComplete() { 100105e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen DragLayer parent = (DragLayer) getParent(); 10025649c287039ea7908112b41604c3fc2893c4697eMichael Jurka if (parent != null) { 10035649c287039ea7908112b41604c3fc2893c4697eMichael Jurka parent.removeView(this); 10045649c287039ea7908112b41604c3fc2893c4697eMichael Jurka } 10054554ee16f122a3dbd9a8d3b828f1c8c7e7b7fe99Adam Cohen mDragController.removeDropTarget((DropTarget) this); 100605e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen clearFocus(); 1007ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderIcon.requestFocus(); 100805e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen 10092801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mRearrangeOnClose) { 1010c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 10112801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = false; 10122801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1013afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 101467bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (!mDragInProgress && !mSuppressFolderDeletion) { 101567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen replaceFolderWithFinalItem(); 101667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } else if (mDragInProgress) { 101767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDeleteFolderOnDropCompleted = true; 101867bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 1019afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 102067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mSuppressFolderDeletion = false; 1021afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1022afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 1023091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void replaceFolderWithFinalItem() { 1024fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // Add the last remaining child to the workspace in place of the folder 1025fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen Runnable onCompleteRunnable = new Runnable() { 1026fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen @Override 1027fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen public void run() { 1028dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screenId); 1029fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 103033231f587e1a6f716af68e6198df774d2847a8e5Winson Chung View child = null; 1031fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // Move the item from the folder to the workspace, in the position of the folder 1032fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen if (getItemCount() == 1) { 1033fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen ShortcutInfo finalItem = mInfo.contents.get(0); 1034c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen child = mLauncher.createShortcut(R.layout.application, cellLayout, 1035fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen finalItem); 1036fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container, 1037dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen mInfo.screenId, mInfo.cellX, mInfo.cellY); 1038fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1039487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (getItemCount() <= 1) { 1040487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // Remove the folder 1041487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, mInfo); 10420eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler if (cellLayout != null) { 10430eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler // b/12446428 -- sometimes the cell layout has already gone away? 10440eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler cellLayout.removeView(mFolderIcon); 10450eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler } 1046487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mFolderIcon instanceof DropTarget) { 1047487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mDragController.removeDropTarget((DropTarget) mFolderIcon); 1048487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1049487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mLauncher.removeFolder(mInfo); 1050487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1051c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen // We add the child after removing the folder to prevent both from existing at 10520e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung // the same time in the CellLayout. We need to add the new item with addInScreenFromBind() 10530e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung // to ensure that hotseat items are placed correctly. 1054c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen if (child != null) { 10550e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung mLauncher.getWorkspace().addInScreenFromBind(child, mInfo.container, mInfo.screenId, 1056c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY); 1057c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen } 1058fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1059fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen }; 1060bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View finalChild = mContent.getLastItem(); 1061fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen if (finalChild != null) { 1062fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable); 106333231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } else { 106433231f587e1a6f716af68e6198df774d2847a8e5Winson Chung onCompleteRunnable.run(); 1065afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1066fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen mDestroyed = true; 1067fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1068afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 1069fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen boolean isDestroyed() { 1070fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return mDestroyed; 10712801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 10722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 1073ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // This method keeps track of the last item in the folder for the purposes 1074ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // of keyboard focus 1075290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void updateTextViewFocus() { 1076bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View lastChild = mContent.getLastItem(); 1077ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen if (lastChild != null) { 1078ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusDownId(lastChild.getId()); 1079ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusRightId(lastChild.getId()); 1080ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusLeftId(lastChild.getId()); 1081ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusUpId(lastChild.getId()); 1082ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen } 1083ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen } 1084ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 1085bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDrop(DragObject d) { 108655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi Runnable cleanUpRunnable = null; 108755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 1088689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen // If we are coming from All Apps space, we defer removing the extra empty screen 1089689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen // until the folder closes 109055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (d.dragSource != mLauncher.getWorkspace() && !(d.dragSource instanceof Folder)) { 109155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi cleanUpRunnable = new Runnable() { 109255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi @Override 109355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void run() { 1094689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen mLauncher.exitSpringLoadedDragModeDelayed(true, 1095689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, 1096689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen null); 109755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 109855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi }; 1099bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 110055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 1101b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // If the icon was dropped while the page was being scrolled, we need to compute 1102b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // the target location again such that the icon is placed of the final page. 1103b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (!mContent.rankOnCurrentPage(mEmptyCellRank)) { 1104b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Reorder again. 1105b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mTargetRank = getTargetRank(d, null); 11064846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 1107b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Rearrange items immediately. 1108b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mReorderAlarmListener.onAlarm(mReorderAlarm); 11094846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 1110b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mOnScrollHintAlarm.cancelAlarm(); 1111b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollPauseAlarm.cancelAlarm(); 11124846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 1113b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.completePendingPageChanges(); 11144846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 111555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi View currentDragView; 111655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi ShortcutInfo si = mCurrentDragInfo; 111755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mIsExternalDrag) { 1118c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal currentDragView = mContent.createAndAddViewForRank(si, mEmptyCellRank); 111995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // Actually move the item in the database if it was an external drag. Call this 112095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // before creating the view, so that ShortcutInfo is updated appropriately. 112195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal LauncherModel.addOrMoveItemInDatabase( 112295abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal mLauncher, si, mInfo.id, 0, si.cellX, si.cellY); 112395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal 112495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // We only need to update the locations if it doesn't get handled in #onDropCompleted. 112595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal if (d.dragSource != this) { 112695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal updateItemLocationsInDatabaseBatch(); 112795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal } 112895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal mIsExternalDrag = false; 112955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 113055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi currentDragView = mCurrentDragView; 1131c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.addViewForRank(currentDragView, si, mEmptyCellRank); 113255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 113355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 113455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (d.dragView.hasDrawn()) { 113555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 113655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Temporarily reset the scale such that the animation target gets calculated correctly. 113755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi float scaleX = getScaleX(); 113855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi float scaleY = getScaleY(); 113955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleX(1.0f); 114055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleY(1.0f); 114155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, currentDragView, 114255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi cleanUpRunnable, null); 114355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleX(scaleX); 114455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleY(scaleY); 114555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 114655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi d.deferDragViewCleanupPostAnimation = false; 114755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi currentDragView.setVisibility(VISIBLE); 114855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 114955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mItemsInvalidated = true; 1150c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 115155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 115255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Temporarily suppress the listener, as we did all the work already here. 115355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mSuppressOnAdd = true; 115455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mInfo.add(si); 115555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mSuppressOnAdd = false; 11564b02017fa5bdb276347d0b9e8a76a9fdd5bb0eb9Sunny Goyal // Clear the drag info, as it is no longer being dragged. 11574b02017fa5bdb276347d0b9e8a76a9fdd5bb0eb9Sunny Goyal mCurrentDragInfo = null; 1158f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mDragInProgress = false; 1159bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 1160bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 11617a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // This is used so the item doesn't immediately appear in the folder when added. In one case 11627a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // we need to create the illusion that the item isn't added back to the folder yet, to 11637a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // to correspond to the animation of the icon back into the folder. This is 11647a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen public void hideItem(ShortcutInfo info) { 11657a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen View v = getViewForInfo(info); 11667a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen v.setVisibility(INVISIBLE); 11677a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 11687a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen public void showItem(ShortcutInfo info) { 11697a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen View v = getViewForInfo(info); 11707a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen v.setVisibility(VISIBLE); 11717a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 11727a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen 1173bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAdd(ShortcutInfo item) { 117405e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // If the item was dropped onto this open folder, we have done the work associated 117505e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // with adding the item to the folder, as indicated by mSuppressOnAdd being set 1176bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (mSuppressOnAdd) return; 11775d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mContent.createAndAddViewForRank(item, mContent.allocateRankForNewItem(item)); 11782e688a8cc217b69cd6cd46a7a408ca3dbfa48cb9Sunny Goyal mItemsInvalidated = true; 1179bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen LauncherModel.addOrMoveItemInDatabase( 1180bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); 1181bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 1182bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 1183a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onRemove(ShortcutInfo item) { 11847c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 118505e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // If this item is being dragged from this open folder, we have already handled 118605e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // the work associated with removing the item, so we don't have to do anything here. 1187bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (item == mCurrentDragInfo) return; 1188df1e4e868a1970b756486dadd652651d40276d36Adam Cohen View v = getViewForInfo(item); 1189290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mContent.removeItem(v); 11902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mState == STATE_ANIMATING) { 11912801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = true; 11922801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 1193c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 11942801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1195afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 1196afb01ee74243cede19088e694ca82cea5983c603Adam Cohen replaceFolderWithFinalItem(); 1197afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1198a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 11997c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen 1200bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal private View getViewForInfo(final ShortcutInfo item) { 1201bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return mContent.iterateOverItems(new ItemOperator() { 1202bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1203bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal @Override 1204bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal public boolean evaluate(ItemInfo info, View view, View parent) { 1205bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return info == item; 1206df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 1207bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal }); 1208df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 1209df1e4e868a1970b756486dadd652651d40276d36Adam Cohen 121076078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen public void onItemsChanged() { 1211ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen updateTextViewFocus(); 121276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 1213ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 121476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onTitleChanged(CharSequence title) { 121576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 121676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 12177c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen public ArrayList<View> getItemsInReadingOrder() { 12187c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (mItemsInvalidated) { 12197c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInReadingOrder.clear(); 1220bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.iterateOverItems(new ItemOperator() { 1221bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1222bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal @Override 1223bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal public boolean evaluate(ItemInfo info, View view, View parent) { 1224bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mItemsInReadingOrder.add(view); 1225bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return false; 12267c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 1227bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal }); 12287c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = false; 12297c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 12307c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen return mItemsInReadingOrder; 12317c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 12328dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 12338dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void getLocationInDragLayer(int[] loc) { 12348dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mLauncher.getDragLayer().getLocationInDragLayer(this, loc); 12358dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 1236ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen 1237ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen public void onFocusChange(View v, boolean hasFocus) { 1238ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen if (v == mFolderName && hasFocus) { 1239ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen startEditingFolderName(); 1240ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen } 1241ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen } 12427d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen 12437d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen @Override 12447d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public void getHitRectRelativeToDragLayer(Rect outRect) { 12457d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen getHitRect(outRect); 12464846193300245c8c0a1f9bde3175f273df044309Sunny Goyal outRect.left -= mScrollAreaOffset; 12474846193300245c8c0a1f9bde3175f273df044309Sunny Goyal outRect.right += mScrollAreaOffset; 12484846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12494846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12504846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private class OnScrollHintListener implements OnAlarmListener { 12514846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12524846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private final DragObject mDragObject; 12534846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal OnScrollHintListener(DragObject object) { 12554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mDragObject = object; 12564846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12574846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12584846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 12594846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Scroll hint has been shown long enough. Now scroll to appropriate page. 12604846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 12614846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 12624846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void onAlarm(Alarm alarm) { 12634846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mCurrentScrollDir == DragController.SCROLL_LEFT) { 1264b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.scrollLeft(); 12654846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 12664846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else if (mCurrentScrollDir == DragController.SCROLL_RIGHT) { 1267b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.scrollRight(); 12684846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 12694846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else { 12704846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // This should not happen 12714846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return; 12724846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12734846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mCurrentScrollDir = DragController.SCROLL_NONE; 12744846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12754846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Pause drag event until the scrolling is finished 12764846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.setOnAlarmListener(new OnScrollFinishedListener(mDragObject)); 12774846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.setAlarm(DragController.RESCROLL_DELAY); 12784846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12794846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private class OnScrollFinishedListener implements OnAlarmListener { 12824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private final DragObject mDragObject; 12844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal OnScrollFinishedListener(DragObject object) { 12864846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mDragObject = object; 12874846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12884846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12894846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 12904846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Page scroll is complete. 12914846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 12924846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 12934846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void onAlarm(Alarm alarm) { 12944846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Reorder immediately on page change. 12954846193300245c8c0a1f9bde3175f273df044309Sunny Goyal onDragOver(mDragObject, 1); 12964846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12977d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen } 129831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1299