Folder.java revision 31abc291deb7a8879fc2ef675814efdb6fa9d56f
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 52e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyalimport com.android.launcher3.CellLayout.CellInfo; 53f406615354a92367481a60966b6b873cae37fe4cSunny Goyalimport com.android.launcher3.DragController.DragListener; 54325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerimport com.android.launcher3.FolderInfo.FolderListener; 55e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyalimport com.android.launcher3.LauncherAccessibilityDelegate.AccessibilityDragSource; 56fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyalimport com.android.launcher3.UninstallDropTarget.UninstallSource; 57bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyalimport com.android.launcher3.Workspace.ItemOperator; 58091440a9cb9d4f42406631004aa484cbb79214caAdam Cohenimport com.android.launcher3.util.Thunk; 59edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 60c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList; 613bf84d3250bf45f2a5b041245e9bd327e03e22c0Adam Cohenimport java.util.Collections; 62c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Represents a set of icons chosen by the user or generated by the system. 6531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 668dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohenpublic class Folder extends LinearLayout implements DragSource, View.OnClickListener, 67ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener, 68e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal View.OnFocusChangeListener, DragListener, UninstallSource, AccessibilityDragSource { 694eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen private static final String TAG = "Launcher.Folder"; 70df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 71c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 72c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * We avoid measuring {@link #mContentWrapper} with a 0 width or height, as this 73c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * results in CellLayout being measured as UNSPECIFIED, which it does not support. 74c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 75c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static final int MIN_CONTENT_DIMEN = 5; 7631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 77df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_NONE = -1; 78df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_SMALL = 0; 79df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_ANIMATING = 1; 80df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_OPEN = 2; 81df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Time for which the scroll hint is shown before automatically changing page. 844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public static final int SCROLL_HINT_DURATION = DragController.SCROLL_DELAY; 864846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 874846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 884846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Fraction of icon width which behave as scroll region. 894846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 904846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private static final float ICON_OVERSCROLL_WIDTH_FACTOR = 0.45f; 914846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 92f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private static final int REORDER_DELAY = 250; 935d518fa77c56a65104f02f40269ad8e43f3431b2Adam Cohen private static final int ON_EXIT_CLOSE_DELAY = 400; 94c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static final Rect sTempRect = new Rect(); 95c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 96c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static String sDefaultFolderName; 97c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static String sHintText; 98c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 99c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final Alarm mReorderAlarm = new Alarm(); 100c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final Alarm mOnExitAlarm = new Alarm(); 101b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal private final Alarm mOnScrollHintAlarm = new Alarm(); 102b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal @Thunk final Alarm mScrollPauseAlarm = new Alarm(); 103c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 104091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>(); 105c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 106c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mExpandDuration; 107c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mMaterialExpandDuration; 108c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mMaterialExpandStagger; 109c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 110c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final InputMethodManager mInputMethodManager; 111c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 112c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected final Launcher mLauncher; 113c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected DragController mDragController; 114c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected FolderInfo mInfo; 115c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 116091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk FolderIcon mFolderIcon; 117c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 118b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal @Thunk FolderPagedView mContent; 119091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk View mContentWrapper; 120c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal FolderEditText mFolderName; 121c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 122290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private View mFooter; 123290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private int mFooterHeight; 124c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 125c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // Cell ranks used for drag and drop 126091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mTargetRank, mPrevTargetRank, mEmptyCellRank; 127c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 128091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mState = STATE_NONE; 129c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private boolean mRearrangeOnClose = false; 1307c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen boolean mItemsInvalidated = false; 131bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private ShortcutInfo mCurrentDragInfo; 132bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private View mCurrentDragView; 13355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi private boolean mIsExternalDrag; 134bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen boolean mSuppressOnAdd = false; 13567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mDragInProgress = false; 13667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mDeleteFolderOnDropCompleted = false; 13767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mSuppressFolderDeletion = false; 13805e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen private boolean mItemAddedBackToSelfViaIcon = false; 139091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk float mFolderIconPivotX; 140091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk float mFolderIconPivotY; 14176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean mIsEditingName = false; 1421960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen 143fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen private boolean mDestroyed; 144fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 145091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk Runnable mDeferredAction; 1461e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka private boolean mDeferDropAfterUninstall; 1471e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka private boolean mUninstallSuccessful; 1481e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 1494846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Folder scrolling 1504846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int mScrollAreaOffset; 1514846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 152091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mScrollHintDir = DragController.SCROLL_NONE; 153091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk int mCurrentScrollDir = DragController.SCROLL_NONE; 1544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 159c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * @param attrs The attributes set containing the Workspace's customization values. 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 16131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Folder(Context context, AttributeSet attrs) { 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setAlwaysDrawnWithCacheEnabled(false); 16476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager = (InputMethodManager) 1658b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 16676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 167c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal Resources res = getResources(); 168c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mExpandDuration = res.getInteger(R.integer.config_folderExpandDuration); 169c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mMaterialExpandDuration = res.getInteger(R.integer.config_materialFolderExpandDuration); 170c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mMaterialExpandStagger = res.getInteger(R.integer.config_materialFolderExpandStagger); 1714ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 1724ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen if (sDefaultFolderName == null) { 1734ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen sDefaultFolderName = res.getString(R.string.folder_name); 1744ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 175a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen if (sHintText == null) { 176a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen sHintText = res.getString(R.string.folder_hint_text); 177a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen } 1784eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen mLauncher = (Launcher) context; 179ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // We need this view to be focusable in touch mode so that when text editing of the folder 180ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // name is complete, we have something to focus on, thus hiding the cursor and giving 181c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // reliable behavior when clicking the text field (since it will always gain focus on click). 182ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen setFocusableInTouchMode(true); 18331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 18631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected void onFinishInflate() { 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.onFinishInflate(); 188c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContentWrapper = findViewById(R.id.folder_content_wrapper); 189b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent = (FolderPagedView) findViewById(R.id.folder_content); 190c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.setFolder(this); 191dcbcc86353e9ed52daac87f292aece667cd0ac71Sunny Goyal 192ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName = (FolderEditText) findViewById(R.id.folder_name); 193ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setFolder(this); 194ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen mFolderName.setOnFocusChangeListener(this); 19576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 19676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen // We disable action mode for now since it messes up the view on phones 19776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback); 19876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setOnEditorActionListener(this); 1994ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setSelectAllOnFocus(true); 2007a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen mFolderName.setInputType(mFolderName.getInputType() | 2017a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS); 202c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 203b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mFooter = findViewById(R.id.folder_footer); 204b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal updateFooterHeight(); 205b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal } 206b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal 207b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal public void updateFooterHeight() { 208290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // We find out how tall footer wants to be (it is set to wrap_content), so that 209c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // we can allocate the appropriate amount of space for it. 210c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int measureSpec = MeasureSpec.UNSPECIFIED; 211290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.measure(measureSpec, measureSpec); 212290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooterHeight = mFooter.getMeasuredHeight(); 21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 21576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { 21676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 21776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 21876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 21976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 22076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onCreateActionMode(ActionMode mode, Menu menu) { 22176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 22276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 22376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 22476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onDestroyActionMode(ActionMode mode) { 22576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 22676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 22776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 22876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 22976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 23076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen }; 23176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onClick(View v) { 233df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 234df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 235b5fe60c8a502fb7e265e3183550478b2b2a49264Adam Cohen mLauncher.onClick(v); 236df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onLongClick(View v) { 24036a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung // Return if global dragging is not enabled 24136a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung if (!mLauncher.isDraggingEnabled()) return true; 242e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal return beginDrag(v, false); 243e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal } 24436a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 245e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal private boolean beginDrag(View v, boolean accessible) { 246df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 247df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 248df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ShortcutInfo item = (ShortcutInfo) tag; 249df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (!v.isInTouchMode()) { 250df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return false; 251df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 252df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 253e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal mLauncher.getWorkspace().beginDragShared(v, new Point(), this, accessible); 25476078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 25576078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen mCurrentDragInfo = item; 256c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mEmptyCellRank = item.rank; 257bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = v; 258fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 259290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mContent.removeItem(mCurrentDragView); 260fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mInfo.remove(mCurrentDragInfo); 26167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDragInProgress = true; 26205e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = false; 263df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 26531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 267e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal @Override 268e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal public void startDrag(CellInfo cellInfo, boolean accessible) { 269e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal beginDrag(cellInfo.cell, accessible); 270e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal } 271e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal 272e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal @Override 273e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal public void enableAccessibleDrag(boolean enable) { 274e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal mLauncher.getSearchBar().enableAccessibleDrag(enable); 275e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal for (int i = 0; i < mContent.getChildCount(); i++) { 276e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal mContent.getPageAt(i).enableAccessibleDrag(enable, CellLayout.FOLDER_ACCESSIBILITY_DRAG); 277e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal } 278e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal mLauncher.getWorkspace().setAddNewPageOnDrag(!enable); 279e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal } 280e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal 28176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean isEditingName() { 28276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mIsEditingName; 28376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 28476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 28576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void startEditingFolderName() { 286a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(""); 28776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = true; 28876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 28976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 29076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void dismissEditingName() { 29176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 29276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen doneEditingFolderName(true); 29376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 29476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 29576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void doneEditingFolderName(boolean commit) { 296a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(sHintText); 2971df26a368a135395b7bd61e9b109044b33b1b0beAdam Cohen // Convert to a string here to ensure that no other state associated with the text field 2981df26a368a135395b7bd61e9b109044b33b1b0beAdam Cohen // gets saved. 2993371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen String newTitle = mFolderName.getText().toString(); 3003371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mInfo.setTitle(newTitle); 30176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen LauncherModel.updateItemInDatabase(mLauncher, mInfo); 302ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 3033371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (commit) { 3043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 3058b805b17158886035b38261eb611d8641701ae43Michael Jurka String.format(getContext().getString(R.string.folder_renamed), newTitle)); 3063371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 307ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // In order to clear the focus from the text field, we set the focus on ourself. This 308ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // ensures that every time the field is clicked, focus is gained, giving reliable behavior. 309ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen requestFocus(); 310ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 311e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohen Selection.setSelection((Spannable) mFolderName.getText(), 0, 0); 31276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = false; 31376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 31476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 31576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 31676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (actionId == EditorInfo.IME_ACTION_DONE) { 31776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen dismissEditingName(); 31876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 31976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 32076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 32176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 32276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 32376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public View getEditTextRegion() { 32476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mFolderName; 32576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 32676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 3270c872ba544ecfd9b106bb66137da8680927590deAdam Cohen /** 3280c872ba544ecfd9b106bb66137da8680927590deAdam Cohen * We need to handle touch events to prevent them from falling through to the workspace below. 3290c872ba544ecfd9b106bb66137da8680927590deAdam Cohen */ 3300c872ba544ecfd9b106bb66137da8680927590deAdam Cohen @Override 3310c872ba544ecfd9b106bb66137da8680927590deAdam Cohen public boolean onTouchEvent(MotionEvent ev) { 3320c872ba544ecfd9b106bb66137da8680927590deAdam Cohen return true; 3330c872ba544ecfd9b106bb66137da8680927590deAdam Cohen } 3340c872ba544ecfd9b106bb66137da8680927590deAdam Cohen 33500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragController(DragController dragController) { 33600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = dragController; 33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 339c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void setFolderIcon(FolderIcon icon) { 3402801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mFolderIcon = icon; 3412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 3422801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 3433371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 3443371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 3453371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // When the folder gets focus, we don't want to announce the list of items. 3463371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 3473371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3483371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 34931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 35031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return the FolderInfo object associated with this folder 35131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 35231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FolderInfo getInfo() { 35331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mInfo; 35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 35531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 35631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void bind(FolderInfo info) { 35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mInfo = info; 358df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ArrayList<ShortcutInfo> children = info.contents; 35908f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal Collections.sort(children, Utilities.RANK_COMPARATOR); 360c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 361c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal ArrayList<ShortcutInfo> overflow = mContent.bindItems(children); 3620057bbcfa4a2ee12c5e87cba8c3fac8eadb078edAdam Cohen 3634ff73887f28b831e8da38f2c417d55350ad88956Jason Monk // If our folder has too many items we prune them from the list. This is an issue 364c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // when upgrading from the old Folders implementation which could contain an unlimited 365c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // number of items. 366c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen for (ShortcutInfo item: overflow) { 367c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen mInfo.remove(item); 368c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, item); 369c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen } 370c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 371c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 372c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal if (lp == null) { 373c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal lp = new DragLayer.LayoutParams(0, 0); 374c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal lp.customPosition = true; 375c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal setLayoutParams(lp); 376c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 377c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal centerAboutIcon(); 378c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 3794dbe6d993485a702505ee4895db94aaa89655f2cAdam Cohen mItemsInvalidated = true; 380ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen updateTextViewFocus(); 381a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen mInfo.addListener(this); 3824ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 383afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (!sDefaultFolderName.contentEquals(mInfo.title)) { 3844ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(mInfo.title); 3854ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } else { 3864ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(""); 3874ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 38833231f587e1a6f716af68e6198df774d2847a8e5Winson Chung 38933231f587e1a6f716af68e6198df774d2847a8e5Winson Chung // In case any children didn't come across during loading, clean up the folder accordingly 39033231f587e1a6f716af68e6198df774d2847a8e5Winson Chung mFolderIcon.post(new Runnable() { 39133231f587e1a6f716af68e6198df774d2847a8e5Winson Chung public void run() { 39233231f587e1a6f716af68e6198df774d2847a8e5Winson Chung if (getItemCount() <= 1) { 39333231f587e1a6f716af68e6198df774d2847a8e5Winson Chung replaceFolderWithFinalItem(); 39433231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } 39533231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } 39633231f587e1a6f716af68e6198df774d2847a8e5Winson Chung }); 397df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 398df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 399df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 400df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Creates a new UserFolder, inflated from R.layout.user_folder. 401df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 402df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @param context The application's context. 403df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 404df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @return A new UserFolder. 405df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 406df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static Folder fromXml(Context context) { 407b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null); 408df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 409df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 410df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 411df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * This method is intended to make the UserFolder to be visually identical in size and position 412df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * to its associated FolderIcon. This allows for a seamless transition into the expanded state. 413df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 414df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private void positionAndSizeAsIcon() { 4153e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (!(getParent() instanceof DragLayer)) return; 416662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setScaleX(0.8f); 417662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setScaleY(0.8f); 418662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setAlpha(0f); 419df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_SMALL; 420df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 421df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 422c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen private void prepareReveal() { 423c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setScaleX(1f); 424c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setScaleY(1f); 425c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setAlpha(1f); 426c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mState = STATE_SMALL; 427c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 4283e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 429c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void animateOpen() { 4308e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 431c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 432b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.completePendingPageChanges(); 4338167dc2dcffbf4f68724bc1db2f5cfc1caf6a848Sunny Goyal if (!mDragInProgress) { 434b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Open on the first page. 435b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.snapToPageImmediately(0); 4364846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4374846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 438c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator openFolderAnim = null; 439c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen final Runnable onCompleteRunnable; 440d794a3f46521b972fa02826d379d1efa112793d2Kenny Guy if (!Utilities.isLmpOrAbove()) { 441c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen positionAndSizeAsIcon(); 442c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen centerAboutIcon(); 443c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 444c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1); 445c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f); 446c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f); 447c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen final ObjectAnimator oa = 448c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 449c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen oa.setDuration(mExpandDuration); 450c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim = oa; 451c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 452c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setLayerType(LAYER_TYPE_HARDWARE, null); 453c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable = new Runnable() { 454c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen @Override 455c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void run() { 456c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setLayerType(LAYER_TYPE_NONE, null); 457c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 458c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen }; 459c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } else { 460c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen prepareReveal(); 461c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen centerAboutIcon(); 462c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 463c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 464c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int height = getFolderHeight(); 465c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 466c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float transX = - 0.075f * (width / 2 - getPivotX()); 467c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float transY = - 0.075f * (height / 2 - getPivotY()); 468c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setTranslationX(transX); 469c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setTranslationY(transY); 470c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder tx = PropertyValuesHolder.ofFloat("translationX", transX, 0); 471c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder ty = PropertyValuesHolder.ofFloat("translationY", transY, 0); 472c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 473c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX()); 474c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY()); 475f7a29e83f06909b378dba39c83a522375682710aSunny Goyal float radius = (float) Math.hypot(rx, ry); 476c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); 477c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator reveal = LauncherAnimUtils.createCircularReveal(this, (int) getPivotX(), 478c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen (int) getPivotY(), 0, radius); 479c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen reveal.setDuration(mMaterialExpandDuration); 480c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 481c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 482bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setAlpha(0f); 483bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal Animator iconsAlpha = LauncherAnimUtils.ofFloat(mContentWrapper, "alpha", 0f, 1f); 484c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setDuration(mMaterialExpandDuration); 485c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setStartDelay(mMaterialExpandStagger); 486c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 487c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 488290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.setAlpha(0f); 489290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal Animator textAlpha = LauncherAnimUtils.ofFloat(mFooter, "alpha", 0f, 1f); 490c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setDuration(mMaterialExpandDuration); 491c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setStartDelay(mMaterialExpandStagger); 492c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 493c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 494c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator drift = LauncherAnimUtils.ofPropertyValuesHolder(this, tx, ty); 495c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setDuration(mMaterialExpandDuration); 496c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setStartDelay(mMaterialExpandStagger); 497c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setInterpolator(new LogDecelerateInterpolator(60, 0)); 498c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 499c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(drift); 500c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(iconsAlpha); 501c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(textAlpha); 502c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(reveal); 503c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 504c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim = anim; 505c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 506bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setLayerType(LAYER_TYPE_HARDWARE, null); 507c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable = new Runnable() { 508c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen @Override 509c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void run() { 510bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setLayerType(LAYER_TYPE_NONE, null); 511c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 512c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen }; 513c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 514c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim.addListener(new AnimatorListenerAdapter() { 515df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 516df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 5173371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 518bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.getAccessibilityDescription()); 519df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 520df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 521df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 522df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 5232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_OPEN; 524c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 525c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen if (onCompleteRunnable != null) { 526c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable.run(); 527c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 52855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 529bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.setFocusOnFirstChild(); 530df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 531df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 532c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim.start(); 53355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 53455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Make sure the folder picks up the last drag move even if the finger doesn't move. 53555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mDragController.isDragging()) { 53655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mDragController.forceTouchMove(); 53755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 53834b6527cefd36fbd5da78464ce9771e379158552Sunny Goyal 539b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal FolderPagedView pages = (FolderPagedView) mContent; 540b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal pages.verifyVisibleHighResIcons(pages.getNextPage()); 54155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 54255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 54355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void beginExternalDrag(ShortcutInfo item) { 54455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mCurrentDragInfo = item; 5455d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mEmptyCellRank = mContent.allocateRankForNewItem(item); 54655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mIsExternalDrag = true; 54755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mDragInProgress = true; 548b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal 549f406615354a92367481a60966b6b873cae37fe4cSunny Goyal // Since this folder opened by another controller, it might not get onDrop or 550f406615354a92367481a60966b6b873cae37fe4cSunny Goyal // onDropComplete. Perform cleanup once drag-n-drop ends. 551f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mDragController.addDragListener(this); 552f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } 553f406615354a92367481a60966b6b873cae37fe4cSunny Goyal 554f406615354a92367481a60966b6b873cae37fe4cSunny Goyal @Override 555f406615354a92367481a60966b6b873cae37fe4cSunny Goyal public void onDragStart(DragSource source, Object info, int dragAction) { } 556f406615354a92367481a60966b6b873cae37fe4cSunny Goyal 557f406615354a92367481a60966b6b873cae37fe4cSunny Goyal @Override 558f406615354a92367481a60966b6b873cae37fe4cSunny Goyal public void onDragEnd() { 559f406615354a92367481a60966b6b873cae37fe4cSunny Goyal if (mIsExternalDrag && mDragInProgress) { 560f406615354a92367481a60966b6b873cae37fe4cSunny Goyal completeDragExit(); 561f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } 562f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mDragController.removeDragListener(this); 563df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 564df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 565091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void sendCustomAccessibilityEvent(int type, String text) { 5668b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 5678b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 5688b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isEnabled()) { 5693371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent event = AccessibilityEvent.obtain(type); 5703371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen onInitializeAccessibilityEvent(event); 5713371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen event.getText().add(text); 5728b805b17158886035b38261eb611d8641701ae43Michael Jurka accessibilityManager.sendAccessibilityEvent(event); 5733371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 5743371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 5753371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 576df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void animateClosed() { 5778e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 578662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0); 579662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f); 580662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f); 581032e6bad1ba588ed8a884fb8f28fb8596efac480Michael Jurka final ObjectAnimator oa = 5822ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 583df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 5842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.addListener(new AnimatorListenerAdapter() { 585df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 586df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 5872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen onCloseComplete(); 5880121c3ea3d5bae176af193ea8ef23ae8a868dd31Michael Jurka setLayerType(LAYER_TYPE_NONE, null); 5892801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_SMALL; 590df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 591df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 592df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 5933371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 5948b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getString(R.string.folder_closed)); 595df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 596df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 597df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 5982801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.setDuration(mExpandDuration); 5990121c3ea3d5bae176af193ea8ef23ae8a868dd31Michael Jurka setLayerType(LAYER_TYPE_HARDWARE, null); 600f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka oa.start(); 601df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 602df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 603cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public boolean acceptDrop(DragObject d) { 604cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen final ItemInfo item = (ItemInfo) d.dragInfo; 605df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen final int itemType = item.itemType; 6062801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || 6072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && 6082801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen !isFull()); 609df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 610df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 611cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDragEnter(DragObject d) { 612c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mPrevTargetRank = -1; 613bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.cancelAlarm(); 614b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Get the area offset such that the folder only closes if half the drag icon width 615b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // is outside the folder area 616b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollAreaOffset = d.dragView.getDragRegionWidth() / 2 - d.xOffset; 617df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 618df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 619bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mReorderAlarmListener = new OnAlarmListener() { 620bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 621c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.realTimeReorder(mEmptyCellRank, mTargetRank); 622c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mEmptyCellRank = mTargetRank; 623bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 624bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 625bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 626c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 6272374abfda3e53f84e005df8923170308e4df8c03Adam Cohen public boolean isLayoutRtl() { 6282374abfda3e53f84e005df8923170308e4df8c03Adam Cohen return (getLayoutDirection() == LAYOUT_DIRECTION_RTL); 6292374abfda3e53f84e005df8923170308e4df8c03Adam Cohen } 6302374abfda3e53f84e005df8923170308e4df8c03Adam Cohen 6314846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 632bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragOver(DragObject d) { 6334846193300245c8c0a1f9bde3175f273df044309Sunny Goyal onDragOver(d, REORDER_DELAY); 6344846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6354846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6364846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int getTargetRank(DragObject d, float[] recycle) { 6374846193300245c8c0a1f9bde3175f273df044309Sunny Goyal recycle = d.getVisualCenter(recycle); 6384846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return mContent.findNearestArea( 6394846193300245c8c0a1f9bde3175f273df044309Sunny Goyal (int) recycle[0] - getPaddingLeft(), (int) recycle[1] - getPaddingTop()); 6404846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6414846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 642091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void onDragOver(DragObject d, int reorderDelay) { 643b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (mScrollPauseAlarm.alarmPending()) { 6444846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return; 6454846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6464846193300245c8c0a1f9bde3175f273df044309Sunny Goyal final float[] r = new float[2]; 6474846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mTargetRank = getTargetRank(d, r); 648f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 649c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal if (mTargetRank != mPrevTargetRank) { 6504cda5b770db7f375a4766fe6c0d657b9d5303374Alan Viverette mReorderAlarm.cancelAlarm(); 651c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal mReorderAlarm.setOnAlarmListener(mReorderAlarmListener); 652c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal mReorderAlarm.setAlarm(REORDER_DELAY); 653c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mPrevTargetRank = mTargetRank; 654bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 6554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6564846193300245c8c0a1f9bde3175f273df044309Sunny Goyal float x = r[0]; 657b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal int currentPage = mContent.getNextPage(); 6584846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 659b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal float cellOverlap = mContent.getCurrentCellLayout().getCellWidth() 6603b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal * ICON_OVERSCROLL_WIDTH_FACTOR; 6613b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal boolean isOutsideLeftEdge = x < cellOverlap; 6623b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal boolean isOutsideRightEdge = x > (getWidth() - cellOverlap); 6634846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 664b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (currentPage > 0 && (mContent.rtlLayout ? isOutsideRightEdge : isOutsideLeftEdge)) { 6653b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal showScrollHint(DragController.SCROLL_LEFT, d); 666b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal } else if (currentPage < (mContent.getPageCount() - 1) 667b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal && (mContent.rtlLayout ? isOutsideLeftEdge : isOutsideRightEdge)) { 6683b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal showScrollHint(DragController.SCROLL_RIGHT, d); 6694846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else { 6704846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.cancelAlarm(); 6714846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mScrollHintDir != DragController.SCROLL_NONE) { 672b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.clearScrollHint(); 6734846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 6744846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6754846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 676df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 677df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 6783b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal private void showScrollHint(int direction, DragObject d) { 6793b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal // Show scroll hint on the right 6803b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal if (mScrollHintDir != direction) { 681b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.showScrollHint(direction); 6823b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mScrollHintDir = direction; 6833b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal } 6843b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 6853b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal // Set alarm for when the hint is complete 6863b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal if (!mOnScrollHintAlarm.alarmPending() || mCurrentScrollDir != direction) { 6873b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mCurrentScrollDir = direction; 6883b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mOnScrollHintAlarm.cancelAlarm(); 6893b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mOnScrollHintAlarm.setOnAlarmListener(new OnScrollHintListener(d)); 6903b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mOnScrollHintAlarm.setAlarm(SCROLL_HINT_DURATION); 6913b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 6923b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mReorderAlarm.cancelAlarm(); 6933b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal mTargetRank = mEmptyCellRank; 6943b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal } 6953b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal } 6963b0883fcda88dd192549055a387fb41e1c2c17adSunny Goyal 697bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mOnExitAlarmListener = new OnAlarmListener() { 698bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 6993e8f811f31a2275e778244427271f77f4116c08bAdam Cohen completeDragExit(); 700bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 701bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 7022801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 70395bb800de9b0142bea0110b074eddbcf0e475736Adam Cohen public void completeDragExit() { 704f406615354a92367481a60966b6b873cae37fe4cSunny Goyal if (mInfo.opened) { 705f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mLauncher.closeFolder(); 706f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mRearrangeOnClose = true; 70731abc291deb7a8879fc2ef675814efdb6fa9d56fSunny Goyal } else if (mState == STATE_ANIMATING) { 70831abc291deb7a8879fc2ef675814efdb6fa9d56fSunny Goyal mRearrangeOnClose = true; 709f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } else { 710f406615354a92367481a60966b6b873cae37fe4cSunny Goyal rearrangeChildren(); 71131abc291deb7a8879fc2ef675814efdb6fa9d56fSunny Goyal clearDragInfo(); 712f406615354a92367481a60966b6b873cae37fe4cSunny Goyal } 71331abc291deb7a8879fc2ef675814efdb6fa9d56fSunny Goyal } 71431abc291deb7a8879fc2ef675814efdb6fa9d56fSunny Goyal 71531abc291deb7a8879fc2ef675814efdb6fa9d56fSunny Goyal private void clearDragInfo() { 7163e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragInfo = null; 7173e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragView = null; 7183e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mSuppressOnAdd = false; 71955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mIsExternalDrag = false; 7203e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 7213e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 722bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragExit(DragObject d) { 72353b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini // We only close the folder if this is a true drag exit, ie. not because 72453b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini // a drop has occurred above the folder. 725bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (!d.dragComplete) { 726bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setOnAlarmListener(mOnExitAlarmListener); 727bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY); 728bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 729bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mReorderAlarm.cancelAlarm(); 7304846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 731b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mOnScrollHintAlarm.cancelAlarm(); 732b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollPauseAlarm.cancelAlarm(); 733b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (mScrollHintDir != DragController.SCROLL_NONE) { 734b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.clearScrollHint(); 735b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 7364846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 7372801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7382801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 739e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal /** 740e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal * When performing an accessibility drop, onDrop is sent immediately after onDragEnter. So we 741e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal * need to complete all transient states based on timers. 742e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal */ 743e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal @Override 744e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal public void prepareAccessibilityDrop() { 745e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal if (mReorderAlarm.alarmPending()) { 746e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal mReorderAlarm.cancelAlarm(); 747e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal mReorderAlarmListener.onAlarm(mReorderAlarm); 748e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal } 749e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal } 750e9b651eef1b9f3647eba94f833bff3fc52f5956bSunny Goyal 7511e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void onDropCompleted(final View target, final DragObject d, 7521e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka final boolean isFlingToDelete, final boolean success) { 7531e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (mDeferDropAfterUninstall) { 754f3007589e346df224d357b389069adfeb266545eMichael Jurka Log.d(TAG, "Deferred handling drop because waiting for uninstall."); 7551e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction = new Runnable() { 7561e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void run() { 7571e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka onDropCompleted(target, d, isFlingToDelete, success); 7581e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction = null; 7591e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7601e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka }; 7611e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka return; 7621e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7631e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 7641e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka boolean beingCalledAfterUninstall = mDeferredAction != null; 7651e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka boolean successfulDrop = 7661e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka success && (!beingCalledAfterUninstall || mUninstallSuccessful); 7675f8afe6280eae34620067696173e71943e1a30a3Winson Chung 7681e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (successfulDrop) { 76955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mDeleteFolderOnDropCompleted && !mItemAddedBackToSelfViaIcon && target != this) { 77067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen replaceFolderWithFinalItem(); 77167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 77267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } else { 77367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen // The drag failed, we need to return the item to the folder 774b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal ShortcutInfo info = (ShortcutInfo) d.dragInfo; 775b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal View icon = (mCurrentDragView != null && mCurrentDragView.getTag() == info) 776b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal ? mCurrentDragView : mContent.createNewView(info); 777b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal ArrayList<View> views = getItemsInReadingOrder(); 778b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal views.add(info.rank, icon); 779b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mContent.arrangeChildren(views, views.size()); 780b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mItemsInvalidated = true; 781b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal 782b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mSuppressOnAdd = true; 78367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mFolderIcon.onDrop(d); 784b8c663c492d32963b6ee33750fc985f037c58f10Sunny Goyal mSuppressOnAdd = false; 78567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 78667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen 78767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (target != this) { 78867bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (mOnExitAlarm.alarmPending()) { 78967bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mOnExitAlarm.cancelAlarm(); 7905455425c1b0355f5dd652cc8e7a2369c33dc9883Michael Jurka if (!successfulDrop) { 7917a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen mSuppressFolderDeletion = true; 7927a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 7935d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.cancelAlarm(); 79467bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen completeDragExit(); 79567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 7969c58d8269b3bdfdbe500b52ccce878ff2edb196bAdam Cohen } 7979c58d8269b3bdfdbe500b52ccce878ff2edb196bAdam Cohen 79867bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDeleteFolderOnDropCompleted = false; 79967bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDragInProgress = false; 80005e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = false; 801bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragInfo = null; 802bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = null; 803bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mSuppressOnAdd = false; 8044045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen 8054045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen // Reordering may have occured, and we need to save the new item locations. We do this once 8064045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen // at the end to prevent unnecessary database operations. 807f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemLocationsInDatabaseBatch(); 8084045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen } 8094045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen 810fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal @Override 8111e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void deferCompleteDropAfterUninstallActivity() { 8121e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferDropAfterUninstall = true; 8131e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 8141e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 815fa401a10e7e9341daf6f3c5949bf9331902c26d0Sunny Goyal @Override 8161e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void onUninstallActivityReturned(boolean success) { 8171e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferDropAfterUninstall = false; 8181e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mUninstallSuccessful = success; 8191e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (mDeferredAction != null) { 8201e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction.run(); 8211e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 8221e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 8231e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 824a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 825eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public float getIntrinsicIconScaleFactor() { 826eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung return 1f; 827eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 828eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 829eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung @Override 830043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public boolean supportsFlingToDelete() { 831043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung return true; 832043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 833043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 8341eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood @Override 8351eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood public boolean supportsAppInfoDropTarget() { 8361eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood return false; 8371eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood } 8381eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood 8391eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood @Override 8401eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood public boolean supportsDeleteDropTarget() { 8411eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood return true; 8421eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood } 8431eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood 844a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onFlingToDelete(DragObject d, int x, int y, PointF vec) { 845a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // Do nothing 846a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 847a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 848a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 849a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onFlingToDeleteCompleted() { 850a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // Do nothing 851a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 852a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 853f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private void updateItemLocationsInDatabaseBatch() { 854f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<View> list = getItemsInReadingOrder(); 855f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 856f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < list.size(); i++) { 857f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen View v = list.get(i); 858f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo info = (ItemInfo) v.getTag(); 85908f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal info.rank = i; 860f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen items.add(info); 861f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 862f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 863f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen LauncherModel.moveItemsInDatabase(mLauncher, items, mInfo.id, 0); 864f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 865f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 866e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen public void addItemLocationsInDatabase() { 867e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen ArrayList<View> list = getItemsInReadingOrder(); 868e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen for (int i = 0; i < list.size(); i++) { 869e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen View v = list.get(i); 870e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen ItemInfo info = (ItemInfo) v.getTag(); 871e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen LauncherModel.addItemToDatabase(mLauncher, info, mInfo.id, 0, 8721d4a2df091e2b5928406ea503321563a0ec8a01eSunny Goyal info.cellX, info.cellY); 873e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 874e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 875e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 87667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen public void notifyDrop() { 87767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (mDragInProgress) { 87805e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = true; 87976078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 880df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 881df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 882df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public boolean isDropEnabled() { 883df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return true; 884df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 885df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 8862801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen public boolean isFull() { 887c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return mContent.isFull(); 8882801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 8892801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 8902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void centerAboutIcon() { 8918e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 8922801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 893892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer); 8942801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 895f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int height = getFolderHeight(); 8968e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen 897c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect); 8982801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 899af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 900af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 901af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung 902c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int centerX = (int) (sTempRect.left + sTempRect.width() * scale / 2); 903c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int centerY = (int) (sTempRect.top + sTempRect.height() * scale / 2); 9042801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredLeft = centerX - width / 2; 9052801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredTop = centerY - height / 2; 9063057b1c259dafc555ff1eec32a9d2f7f81bb0bdaWinson Chung int currentPage = mLauncher.getWorkspace().getNextPage(); 9077cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // In case the workspace is scrolling, we need to use the final scroll to compute 9087cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // the folders bounds. 9097cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen mLauncher.getWorkspace().setFinalScrollForPageChange(currentPage); 91035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We first fetch the currently visible CellLayoutChildren 9117cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage); 912a52570f8f9ad65b85e33a2f2e87722f9edd6c6f4Michael Jurka ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets(); 91335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen Rect bounds = new Rect(); 91435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen parent.getDescendantRectRelativeToSelf(boundingLayout, bounds); 9157cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // We reset the workspaces scroll 9167cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen mLauncher.getWorkspace().resetFinalScrollForPageChange(currentPage); 91735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 91835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We need to bound the folder to the currently visible CellLayoutChildren 91935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int left = Math.min(Math.max(bounds.left, centeredLeft), 92035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.left + bounds.width() - width); 92135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int top = Math.min(Math.max(bounds.top, centeredTop), 92235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.top + bounds.height() - height); 923af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung if (grid.isPhone() && (grid.availableWidthPx - width) < grid.iconSizePx) { 924af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung // Center the folder if it is full (on phones only) 925af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung left = (grid.availableWidthPx - width) / 2; 926af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung } else if (width >= bounds.width()) { 927af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung // If the folder doesn't fit within the bounds, center it about the desired bounds 92835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen left = bounds.left + (bounds.width() - width) / 2; 92935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 93035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen if (height >= bounds.height()) { 93135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen top = bounds.top + (bounds.height() - height) / 2; 9320e4857c302da6adbd45231d7a8bae0289fa33250Adam Cohen } 9332801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 9342801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotX = width / 2 + (centeredLeft - left); 9352801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotY = height / 2 + (centeredTop - top); 9362801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotX(folderPivotX); 9372801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotY(folderPivotY); 938268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * 9392801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotX / width)); 940268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * 9412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotY / height)); 9423bf84d3250bf45f2a5b041245e9bd327e03e22c0Adam Cohen 943662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.width = width; 944662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.height = height; 945662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.x = left; 946662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.y = top; 9472801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 9482801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 949268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen float getPivotXForIconAnimation() { 950268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen return mFolderIconPivotX; 951268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen } 952268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen float getPivotYForIconAnimation() { 953268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen return mFolderIconPivotY; 954268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen } 955268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen 956892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung private int getContentAreaHeight() { 957892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 958892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 959892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung Rect workspacePadding = grid.getWorkspacePadding(grid.isLandscape ? 960892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung CellLayout.LANDSCAPE : CellLayout.PORTRAIT); 961892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung int maxContentAreaHeight = grid.availableHeightPx - 962892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung workspacePadding.top - workspacePadding.bottom - 963290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooterHeight; 9641960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen int height = Math.min(maxContentAreaHeight, 965892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung mContent.getDesiredHeight()); 9661960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen return Math.max(height, MIN_CONTENT_DIMEN); 9671960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen } 9681960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen 9691960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen private int getContentAreaWidth() { 9701960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen return Math.max(mContent.getDesiredWidth(), MIN_CONTENT_DIMEN); 971892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung } 972892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 973f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private int getFolderHeight() { 974c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return getFolderHeight(getContentAreaHeight()); 975c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 976c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 977c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private int getFolderHeight(int contentAreaHeight) { 978290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return getPaddingTop() + getPaddingBottom() + contentAreaHeight + mFooterHeight; 979f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 980f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 981f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 982c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentWidth = getContentAreaWidth(); 983c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentHeight = getContentAreaHeight(); 9842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 985c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(contentWidth, MeasureSpec.EXACTLY); 986c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY); 987c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 988c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.setFixedSize(contentWidth, contentHeight); 989c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContentWrapper.measure(contentAreaWidthSpec, contentAreaHeightSpec); 990290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.measure(contentAreaWidthSpec, 991290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal MeasureSpec.makeMeasureSpec(mFooterHeight, MeasureSpec.EXACTLY)); 992c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 993c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int folderWidth = getPaddingLeft() + getPaddingRight() + contentWidth; 994c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int folderHeight = getFolderHeight(contentHeight); 995c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal setMeasuredDimension(folderWidth, folderHeight); 996c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 997c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 998c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 999c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * Rearranges the children based on their rank. 1000c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 1001c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void rearrangeChildren() { 1002c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(-1); 1003c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 1004c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 1005c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 1006c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * Rearranges the children based on their rank. 1007c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * @param itemCount if greater than the total children count, empty spaces are left at the end, 1008c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * otherwise it is ignored. 1009c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 1010c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void rearrangeChildren(int itemCount) { 1011c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal ArrayList<View> views = getItemsInReadingOrder(); 1012c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.arrangeChildren(views, Math.max(itemCount, views.size())); 10137c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 10142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 10152801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 1016c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal // TODO remove this once GSA code fix is submitted 1017c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal public ViewGroup getContent() { 1018c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal return (ViewGroup) mContent; 1019c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal } 1020c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal 1021a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public int getItemCount() { 1022c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return mContent.getItemCount(); 1023a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 1024a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 1025091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void onCloseComplete() { 102605e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen DragLayer parent = (DragLayer) getParent(); 10275649c287039ea7908112b41604c3fc2893c4697eMichael Jurka if (parent != null) { 10285649c287039ea7908112b41604c3fc2893c4697eMichael Jurka parent.removeView(this); 10295649c287039ea7908112b41604c3fc2893c4697eMichael Jurka } 10304554ee16f122a3dbd9a8d3b828f1c8c7e7b7fe99Adam Cohen mDragController.removeDropTarget((DropTarget) this); 103105e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen clearFocus(); 1032ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderIcon.requestFocus(); 103305e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen 10342801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mRearrangeOnClose) { 1035c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 10362801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = false; 10372801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1038afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 103967bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (!mDragInProgress && !mSuppressFolderDeletion) { 104067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen replaceFolderWithFinalItem(); 104167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } else if (mDragInProgress) { 104267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDeleteFolderOnDropCompleted = true; 104367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 1044afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 104567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mSuppressFolderDeletion = false; 104631abc291deb7a8879fc2ef675814efdb6fa9d56fSunny Goyal clearDragInfo(); 1047afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1048afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 1049091440a9cb9d4f42406631004aa484cbb79214caAdam Cohen @Thunk void replaceFolderWithFinalItem() { 1050fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // Add the last remaining child to the workspace in place of the folder 1051fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen Runnable onCompleteRunnable = new Runnable() { 1052fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen @Override 1053fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen public void run() { 1054dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screenId); 1055fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 105633231f587e1a6f716af68e6198df774d2847a8e5Winson Chung View child = null; 1057fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // Move the item from the folder to the workspace, in the position of the folder 1058fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen if (getItemCount() == 1) { 1059fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen ShortcutInfo finalItem = mInfo.contents.get(0); 1060c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen child = mLauncher.createShortcut(R.layout.application, cellLayout, 1061fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen finalItem); 1062fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container, 1063dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen mInfo.screenId, mInfo.cellX, mInfo.cellY); 1064fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1065487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (getItemCount() <= 1) { 1066487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // Remove the folder 1067487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, mInfo); 10680eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler if (cellLayout != null) { 10690eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler // b/12446428 -- sometimes the cell layout has already gone away? 10700eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler cellLayout.removeView(mFolderIcon); 10710eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler } 1072487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mFolderIcon instanceof DropTarget) { 1073487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mDragController.removeDropTarget((DropTarget) mFolderIcon); 1074487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1075487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mLauncher.removeFolder(mInfo); 1076487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1077c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen // We add the child after removing the folder to prevent both from existing at 10780e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung // the same time in the CellLayout. We need to add the new item with addInScreenFromBind() 10790e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung // to ensure that hotseat items are placed correctly. 1080c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen if (child != null) { 10810e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung mLauncher.getWorkspace().addInScreenFromBind(child, mInfo.container, mInfo.screenId, 1082c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY); 1083c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen } 1084fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1085fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen }; 1086bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View finalChild = mContent.getLastItem(); 1087fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen if (finalChild != null) { 1088fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable); 108933231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } else { 109033231f587e1a6f716af68e6198df774d2847a8e5Winson Chung onCompleteRunnable.run(); 1091afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1092fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen mDestroyed = true; 1093fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1094afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 1095fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen boolean isDestroyed() { 1096fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return mDestroyed; 10972801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 10982801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 1099ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // This method keeps track of the last item in the folder for the purposes 1100ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // of keyboard focus 1101290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void updateTextViewFocus() { 1102bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View lastChild = mContent.getLastItem(); 1103ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen if (lastChild != null) { 1104ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusDownId(lastChild.getId()); 1105ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusRightId(lastChild.getId()); 1106ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusLeftId(lastChild.getId()); 1107ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusUpId(lastChild.getId()); 1108ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen } 1109ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen } 1110ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 1111bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDrop(DragObject d) { 111255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi Runnable cleanUpRunnable = null; 111355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 1114689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen // If we are coming from All Apps space, we defer removing the extra empty screen 1115689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen // until the folder closes 111655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (d.dragSource != mLauncher.getWorkspace() && !(d.dragSource instanceof Folder)) { 111755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi cleanUpRunnable = new Runnable() { 111855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi @Override 111955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void run() { 1120689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen mLauncher.exitSpringLoadedDragModeDelayed(true, 1121689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, 1122689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen null); 112355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 112455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi }; 1125bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 112655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 1127b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // If the icon was dropped while the page was being scrolled, we need to compute 1128b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // the target location again such that the icon is placed of the final page. 1129b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal if (!mContent.rankOnCurrentPage(mEmptyCellRank)) { 1130b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Reorder again. 1131b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mTargetRank = getTargetRank(d, null); 11324846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 1133b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal // Rearrange items immediately. 1134b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mReorderAlarmListener.onAlarm(mReorderAlarm); 11354846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 1136b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mOnScrollHintAlarm.cancelAlarm(); 1137b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mScrollPauseAlarm.cancelAlarm(); 11384846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 1139b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.completePendingPageChanges(); 11404846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 114155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi View currentDragView; 114255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi ShortcutInfo si = mCurrentDragInfo; 114355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mIsExternalDrag) { 1144c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal currentDragView = mContent.createAndAddViewForRank(si, mEmptyCellRank); 114595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // Actually move the item in the database if it was an external drag. Call this 114695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // before creating the view, so that ShortcutInfo is updated appropriately. 114795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal LauncherModel.addOrMoveItemInDatabase( 114895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal mLauncher, si, mInfo.id, 0, si.cellX, si.cellY); 114995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal 115095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // We only need to update the locations if it doesn't get handled in #onDropCompleted. 115195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal if (d.dragSource != this) { 115295abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal updateItemLocationsInDatabaseBatch(); 115395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal } 115495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal mIsExternalDrag = false; 115555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 115655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi currentDragView = mCurrentDragView; 1157c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.addViewForRank(currentDragView, si, mEmptyCellRank); 115855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 115955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 116055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (d.dragView.hasDrawn()) { 116155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 116255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Temporarily reset the scale such that the animation target gets calculated correctly. 116355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi float scaleX = getScaleX(); 116455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi float scaleY = getScaleY(); 116555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleX(1.0f); 116655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleY(1.0f); 116755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, currentDragView, 116855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi cleanUpRunnable, null); 116955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleX(scaleX); 117055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleY(scaleY); 117155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 117255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi d.deferDragViewCleanupPostAnimation = false; 117355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi currentDragView.setVisibility(VISIBLE); 117455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 117555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mItemsInvalidated = true; 1176c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 117755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 117855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Temporarily suppress the listener, as we did all the work already here. 117955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mSuppressOnAdd = true; 118055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mInfo.add(si); 118155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mSuppressOnAdd = false; 11824b02017fa5bdb276347d0b9e8a76a9fdd5bb0eb9Sunny Goyal // Clear the drag info, as it is no longer being dragged. 11834b02017fa5bdb276347d0b9e8a76a9fdd5bb0eb9Sunny Goyal mCurrentDragInfo = null; 1184f406615354a92367481a60966b6b873cae37fe4cSunny Goyal mDragInProgress = false; 1185bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 1186bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 11877a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // This is used so the item doesn't immediately appear in the folder when added. In one case 11887a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // we need to create the illusion that the item isn't added back to the folder yet, to 11897a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // to correspond to the animation of the icon back into the folder. This is 11907a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen public void hideItem(ShortcutInfo info) { 11917a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen View v = getViewForInfo(info); 11927a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen v.setVisibility(INVISIBLE); 11937a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 11947a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen public void showItem(ShortcutInfo info) { 11957a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen View v = getViewForInfo(info); 11967a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen v.setVisibility(VISIBLE); 11977a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 11987a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen 1199bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAdd(ShortcutInfo item) { 120005e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // If the item was dropped onto this open folder, we have done the work associated 120105e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // with adding the item to the folder, as indicated by mSuppressOnAdd being set 1202bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (mSuppressOnAdd) return; 12035d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mContent.createAndAddViewForRank(item, mContent.allocateRankForNewItem(item)); 12042e688a8cc217b69cd6cd46a7a408ca3dbfa48cb9Sunny Goyal mItemsInvalidated = true; 1205bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen LauncherModel.addOrMoveItemInDatabase( 1206bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); 1207bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 1208bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 1209a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onRemove(ShortcutInfo item) { 12107c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 121105e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // If this item is being dragged from this open folder, we have already handled 121205e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // the work associated with removing the item, so we don't have to do anything here. 1213bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (item == mCurrentDragInfo) return; 1214df1e4e868a1970b756486dadd652651d40276d36Adam Cohen View v = getViewForInfo(item); 1215290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mContent.removeItem(v); 12162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mState == STATE_ANIMATING) { 12172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = true; 12182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 1219c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 12202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1221afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 1222afb01ee74243cede19088e694ca82cea5983c603Adam Cohen replaceFolderWithFinalItem(); 1223afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1224a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 12257c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen 1226bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal private View getViewForInfo(final ShortcutInfo item) { 1227bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return mContent.iterateOverItems(new ItemOperator() { 1228bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1229bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal @Override 1230bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal public boolean evaluate(ItemInfo info, View view, View parent) { 1231bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return info == item; 1232df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 1233bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal }); 1234df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 1235df1e4e868a1970b756486dadd652651d40276d36Adam Cohen 123676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen public void onItemsChanged() { 1237ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen updateTextViewFocus(); 123876078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 1239ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 124076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onTitleChanged(CharSequence title) { 124176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 124276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 12437c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen public ArrayList<View> getItemsInReadingOrder() { 12447c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (mItemsInvalidated) { 12457c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInReadingOrder.clear(); 1246bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.iterateOverItems(new ItemOperator() { 1247bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1248bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal @Override 1249bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal public boolean evaluate(ItemInfo info, View view, View parent) { 1250bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mItemsInReadingOrder.add(view); 1251bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return false; 12527c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 1253bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal }); 12547c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = false; 12557c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 12567c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen return mItemsInReadingOrder; 12577c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 12588dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 12598dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void getLocationInDragLayer(int[] loc) { 12608dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mLauncher.getDragLayer().getLocationInDragLayer(this, loc); 12618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 1262ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen 1263ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen public void onFocusChange(View v, boolean hasFocus) { 1264ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen if (v == mFolderName && hasFocus) { 1265ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen startEditingFolderName(); 1266ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen } 1267ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen } 12687d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen 12697d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen @Override 12707d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public void getHitRectRelativeToDragLayer(Rect outRect) { 12717d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen getHitRect(outRect); 12724846193300245c8c0a1f9bde3175f273df044309Sunny Goyal outRect.left -= mScrollAreaOffset; 12734846193300245c8c0a1f9bde3175f273df044309Sunny Goyal outRect.right += mScrollAreaOffset; 12744846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12754846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12764846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private class OnScrollHintListener implements OnAlarmListener { 12774846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12784846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private final DragObject mDragObject; 12794846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal OnScrollHintListener(DragObject object) { 12814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mDragObject = object; 12824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 12854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Scroll hint has been shown long enough. Now scroll to appropriate page. 12864846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 12874846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 12884846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void onAlarm(Alarm alarm) { 12894846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mCurrentScrollDir == DragController.SCROLL_LEFT) { 1290b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.scrollLeft(); 12914846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 12924846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else if (mCurrentScrollDir == DragController.SCROLL_RIGHT) { 1293b863415c17aaaf6012647df5ed14803f89f94bcbSunny Goyal mContent.scrollRight(); 12944846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 12954846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else { 12964846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // This should not happen 12974846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return; 12984846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12994846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mCurrentScrollDir = DragController.SCROLL_NONE; 13004846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 13014846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Pause drag event until the scrolling is finished 13024846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.setOnAlarmListener(new OnScrollFinishedListener(mDragObject)); 13034846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.setAlarm(DragController.RESCROLL_DELAY); 13044846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 13054846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 13064846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 13074846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private class OnScrollFinishedListener implements OnAlarmListener { 13084846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 13094846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private final DragObject mDragObject; 13104846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 13114846193300245c8c0a1f9bde3175f273df044309Sunny Goyal OnScrollFinishedListener(DragObject object) { 13124846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mDragObject = object; 13134846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 13144846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 13154846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 13164846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Page scroll is complete. 13174846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 13184846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 13194846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void onAlarm(Alarm alarm) { 13204846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Reorder immediately on page change. 13214846193300245c8c0a1f9bde3175f273df044309Sunny Goyal onDragOver(mDragObject, 1); 13224846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 13237d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen } 132431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1325