Folder.java revision 5d85c44fd873c740dc191b28424c2ee367d730a2
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 52325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerimport com.android.launcher3.FolderInfo.FolderListener; 53bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyalimport com.android.launcher3.Workspace.ItemOperator; 54edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 55c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList; 563bf84d3250bf45f2a5b041245e9bd327e03e22c0Adam Cohenimport java.util.Collections; 57c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 5831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Represents a set of icons chosen by the user or generated by the system. 6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 618dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohenpublic class Folder extends LinearLayout implements DragSource, View.OnClickListener, 62ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener, 63ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen View.OnFocusChangeListener { 644eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen private static final String TAG = "Launcher.Folder"; 65df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 66c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 67c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * We avoid measuring {@link #mContentWrapper} with a 0 width or height, as this 68c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * results in CellLayout being measured as UNSPECIFIED, which it does not support. 69c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 70c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static final int MIN_CONTENT_DIMEN = 5; 71290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private static final boolean ALLOW_FOLDER_SCROLL = true; 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 73df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_NONE = -1; 74df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_SMALL = 0; 75df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_ANIMATING = 1; 76df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_OPEN = 2; 77df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 784846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 794846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Fraction of the width to scroll when showing the next page hint. 804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private static final float SCROLL_HINT_FRACTION = 0.07f; 824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Time for which the scroll hint is shown before automatically changing page. 854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 864846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public static final int SCROLL_HINT_DURATION = DragController.SCROLL_DELAY; 874846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 884846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 895d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal * Time in milliseconds for which an icon sticks to the target position 905d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal * in case of a sorted folder. 915d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal */ 925d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal private static final int SORTED_STICKY_REORDER_DELAY = 1500; 935d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 945d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal /** 954846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Fraction of icon width which behave as scroll region. 964846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 974846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private static final float ICON_OVERSCROLL_WIDTH_FACTOR = 0.45f; 984846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 99f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private static final int REORDER_DELAY = 250; 1005d518fa77c56a65104f02f40269ad8e43f3431b2Adam Cohen private static final int ON_EXIT_CLOSE_DELAY = 400; 101c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static final Rect sTempRect = new Rect(); 102c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 103c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static String sDefaultFolderName; 104c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private static String sHintText; 105c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 106c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final Alarm mReorderAlarm = new Alarm(); 107c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final Alarm mOnExitAlarm = new Alarm(); 108c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 109c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>(); 110c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 111c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mExpandDuration; 112c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mMaterialExpandDuration; 113c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final int mMaterialExpandStagger; 114c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 115c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private final InputMethodManager mInputMethodManager; 116c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 117c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected final Launcher mLauncher; 118c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected DragController mDragController; 119c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal protected FolderInfo mInfo; 120c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 1212801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private FolderIcon mFolderIcon; 122c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 123bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal private FolderContent mContent; 124c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private View mContentWrapper; 125c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal FolderEditText mFolderName; 126c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 127290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private View mFooter; 128290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal private int mFooterHeight; 129c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 130c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // Cell ranks used for drag and drop 131c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private int mTargetRank, mPrevTargetRank, mEmptyCellRank; 132c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 133c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private int mState = STATE_NONE; 134c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private boolean mRearrangeOnClose = false; 1357c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen boolean mItemsInvalidated = false; 136bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private ShortcutInfo mCurrentDragInfo; 137bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private View mCurrentDragView; 13855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi private boolean mIsExternalDrag; 139bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen boolean mSuppressOnAdd = false; 14067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mDragInProgress = false; 14167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mDeleteFolderOnDropCompleted = false; 14267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen private boolean mSuppressFolderDeletion = false; 14305e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen private boolean mItemAddedBackToSelfViaIcon = false; 144268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen private float mFolderIconPivotX; 145268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen private float mFolderIconPivotY; 14676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean mIsEditingName = false; 1471960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen 148fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen private boolean mDestroyed; 149fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 1501e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka private Runnable mDeferredAction; 1511e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka private boolean mDeferDropAfterUninstall; 1521e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka private boolean mUninstallSuccessful; 1531e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 1544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Folder scrolling 1554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int mScrollAreaOffset; 1564846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private Alarm mOnScrollHintAlarm; 1574846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private Alarm mScrollPauseAlarm; 1584846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 1594846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // TODO: Use {@link #mContent} once {@link #ALLOW_FOLDER_SCROLL} is removed. 1604846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private FolderPagedView mPagedView; 1614846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 1624846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int mScrollHintDir = DragController.SCROLL_NONE; 1634846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int mCurrentScrollDir = DragController.SCROLL_NONE; 1644846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 16631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 16831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 169c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * @param attrs The attributes set containing the Workspace's customization values. 17031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Folder(Context context, AttributeSet attrs) { 17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setAlwaysDrawnWithCacheEnabled(false); 17476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager = (InputMethodManager) 1758b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 17676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 177c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal Resources res = getResources(); 178c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mExpandDuration = res.getInteger(R.integer.config_folderExpandDuration); 179c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mMaterialExpandDuration = res.getInteger(R.integer.config_materialFolderExpandDuration); 180c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mMaterialExpandStagger = res.getInteger(R.integer.config_materialFolderExpandStagger); 1814ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 1824ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen if (sDefaultFolderName == null) { 1834ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen sDefaultFolderName = res.getString(R.string.folder_name); 1844ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 185a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen if (sHintText == null) { 186a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen sHintText = res.getString(R.string.folder_hint_text); 187a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen } 1884eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen mLauncher = (Launcher) context; 189ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // We need this view to be focusable in touch mode so that when text editing of the folder 190ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // name is complete, we have something to focus on, thus hiding the cursor and giving 191c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // reliable behavior when clicking the text field (since it will always gain focus on click). 192ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen setFocusableInTouchMode(true); 1934846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 1944846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (ALLOW_FOLDER_SCROLL) { 1954846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm = new Alarm(); 1964846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm = new Alarm(); 1974846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 19831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 19931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 20131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected void onFinishInflate() { 20231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.onFinishInflate(); 203c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContentWrapper = findViewById(R.id.folder_content_wrapper); 204bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent = (FolderContent) findViewById(R.id.folder_content); 205c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.setFolder(this); 206dcbcc86353e9ed52daac87f292aece667cd0ac71Sunny Goyal 207ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName = (FolderEditText) findViewById(R.id.folder_name); 208ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setFolder(this); 209ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen mFolderName.setOnFocusChangeListener(this); 21076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 21176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen // We disable action mode for now since it messes up the view on phones 21276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback); 21376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setOnEditorActionListener(this); 2144ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setSelectAllOnFocus(true); 2157a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen mFolderName.setInputType(mFolderName.getInputType() | 2167a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS); 217c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 218290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter = ALLOW_FOLDER_SCROLL ? findViewById(R.id.folder_footer) : mFolderName; 219290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal // We find out how tall footer wants to be (it is set to wrap_content), so that 220c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal // we can allocate the appropriate amount of space for it. 221c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int measureSpec = MeasureSpec.UNSPECIFIED; 222290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.measure(measureSpec, measureSpec); 223290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooterHeight = mFooter.getMeasuredHeight(); 2244846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 2254846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (ALLOW_FOLDER_SCROLL) { 2264846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView = (FolderPagedView) mContent; 2274846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2292801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 23076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { 23176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 23276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 23376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 23476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 23576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onCreateActionMode(ActionMode mode, Menu menu) { 23676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 23776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 23876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 23976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onDestroyActionMode(ActionMode mode) { 24076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 24176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 24276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 24376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 24476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 24576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen }; 24676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 24731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onClick(View v) { 248df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 249df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 250b5fe60c8a502fb7e265e3183550478b2b2a49264Adam Cohen mLauncher.onClick(v); 251df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 25231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onLongClick(View v) { 25536a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung // Return if global dragging is not enabled 25636a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung if (!mLauncher.isDraggingEnabled()) return true; 25736a62fe917be0a2520c457f985075fb5d3d09d1cWinson Chung 258df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 259df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 260df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ShortcutInfo item = (ShortcutInfo) tag; 261df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (!v.isInTouchMode()) { 262df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return false; 263df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 264df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 265b745afbdd75157c73d581b345118cdaff99e912dWinson Chung mLauncher.getWorkspace().beginDragShared(v, new Point(), this, false); 26676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 26776078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen mCurrentDragInfo = item; 268c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mEmptyCellRank = item.rank; 269bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = v; 270fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 271290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mContent.removeItem(mCurrentDragView); 272fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mInfo.remove(mCurrentDragInfo); 27367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDragInProgress = true; 27405e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = false; 275df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 27976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean isEditingName() { 28076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mIsEditingName; 28176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 28276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 28376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void startEditingFolderName() { 284a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(""); 28576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = true; 28676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 28776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 28876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void dismissEditingName() { 28976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 29076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen doneEditingFolderName(true); 29176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 29276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 29376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void doneEditingFolderName(boolean commit) { 294a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(sHintText); 2951df26a368a135395b7bd61e9b109044b33b1b0beAdam Cohen // Convert to a string here to ensure that no other state associated with the text field 2961df26a368a135395b7bd61e9b109044b33b1b0beAdam Cohen // gets saved. 2973371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen String newTitle = mFolderName.getText().toString(); 2983371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen mInfo.setTitle(newTitle); 29976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen LauncherModel.updateItemInDatabase(mLauncher, mInfo); 300ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 3013371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen if (commit) { 3023371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 3038b805b17158886035b38261eb611d8641701ae43Michael Jurka String.format(getContext().getString(R.string.folder_renamed), newTitle)); 3043371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 305ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // In order to clear the focus from the text field, we set the focus on ourself. This 306ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // ensures that every time the field is clicked, focus is gained, giving reliable behavior. 307ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen requestFocus(); 308ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 309e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohen Selection.setSelection((Spannable) mFolderName.getText(), 0, 0); 31076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = false; 31176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 31276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 31376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 31476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (actionId == EditorInfo.IME_ACTION_DONE) { 31576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen dismissEditingName(); 31676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 31776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 31876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 31976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 32076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 32176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public View getEditTextRegion() { 32276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mFolderName; 32376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 32476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 3250c872ba544ecfd9b106bb66137da8680927590deAdam Cohen /** 3260c872ba544ecfd9b106bb66137da8680927590deAdam Cohen * We need to handle touch events to prevent them from falling through to the workspace below. 3270c872ba544ecfd9b106bb66137da8680927590deAdam Cohen */ 3280c872ba544ecfd9b106bb66137da8680927590deAdam Cohen @Override 3290c872ba544ecfd9b106bb66137da8680927590deAdam Cohen public boolean onTouchEvent(MotionEvent ev) { 3300c872ba544ecfd9b106bb66137da8680927590deAdam Cohen return true; 3310c872ba544ecfd9b106bb66137da8680927590deAdam Cohen } 3320c872ba544ecfd9b106bb66137da8680927590deAdam Cohen 33300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragController(DragController dragController) { 33400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = dragController; 33531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 337c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void setFolderIcon(FolderIcon icon) { 3382801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mFolderIcon = icon; 3392801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 3402801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 3413371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen @Override 3423371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { 3433371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen // When the folder gets focus, we don't want to announce the list of items. 3443371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen return true; 3453371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 3463371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 34731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 34831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return the FolderInfo object associated with this folder 34931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 35031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FolderInfo getInfo() { 35131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mInfo; 35231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 35331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void bind(FolderInfo info) { 35531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mInfo = info; 356df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ArrayList<ShortcutInfo> children = info.contents; 35708f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal Collections.sort(children, Utilities.RANK_COMPARATOR); 358c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 359c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal ArrayList<ShortcutInfo> overflow = mContent.bindItems(children); 3600057bbcfa4a2ee12c5e87cba8c3fac8eadb078edAdam Cohen 3614ff73887f28b831e8da38f2c417d55350ad88956Jason Monk // If our folder has too many items we prune them from the list. This is an issue 362c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // when upgrading from the old Folders implementation which could contain an unlimited 363c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // number of items. 364c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen for (ShortcutInfo item: overflow) { 365c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen mInfo.remove(item); 366c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, item); 367c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen } 368c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 369c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 370c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal if (lp == null) { 371c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal lp = new DragLayer.LayoutParams(0, 0); 372c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal lp.customPosition = true; 373c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal setLayoutParams(lp); 374c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 375c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal centerAboutIcon(); 376c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 3774dbe6d993485a702505ee4895db94aaa89655f2cAdam Cohen mItemsInvalidated = true; 378ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen updateTextViewFocus(); 379a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen mInfo.addListener(this); 3804ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 381afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (!sDefaultFolderName.contentEquals(mInfo.title)) { 3824ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(mInfo.title); 3834ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } else { 3844ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(""); 3854ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 38633231f587e1a6f716af68e6198df774d2847a8e5Winson Chung 38733231f587e1a6f716af68e6198df774d2847a8e5Winson Chung // In case any children didn't come across during loading, clean up the folder accordingly 38833231f587e1a6f716af68e6198df774d2847a8e5Winson Chung mFolderIcon.post(new Runnable() { 38933231f587e1a6f716af68e6198df774d2847a8e5Winson Chung public void run() { 39033231f587e1a6f716af68e6198df774d2847a8e5Winson Chung if (getItemCount() <= 1) { 39133231f587e1a6f716af68e6198df774d2847a8e5Winson Chung replaceFolderWithFinalItem(); 39233231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } 39333231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } 39433231f587e1a6f716af68e6198df774d2847a8e5Winson Chung }); 395df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 396df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 397df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 398df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Creates a new UserFolder, inflated from R.layout.user_folder. 399df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 400df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @param context The application's context. 401df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 402df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @return A new UserFolder. 403df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 404df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static Folder fromXml(Context context) { 405290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return (Folder) LayoutInflater.from(context).inflate( 406290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal ALLOW_FOLDER_SCROLL ? R.layout.user_folder_scroll : R.layout.user_folder, null); 407df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 408df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 409df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 410df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * This method is intended to make the UserFolder to be visually identical in size and position 411df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * to its associated FolderIcon. This allows for a seamless transition into the expanded state. 412df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 413df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private void positionAndSizeAsIcon() { 4143e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (!(getParent() instanceof DragLayer)) return; 415662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setScaleX(0.8f); 416662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setScaleY(0.8f); 417662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen setAlpha(0f); 418df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_SMALL; 419df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 420df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 421c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen private void prepareReveal() { 422c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setScaleX(1f); 423c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setScaleY(1f); 424c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setAlpha(1f); 425c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen mState = STATE_SMALL; 426c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 4273e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 428c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void animateOpen() { 4298e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 430c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 4314846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (ALLOW_FOLDER_SCROLL) { 4325d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mPagedView.completePendingPageChanges(); 4335d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal if (!(mDragInProgress && mPagedView.mIsSorted)) { 4345d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal // Open on the first page. 4355d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mPagedView.snapToPageImmediately(0); 4365d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal } 4374846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 4384846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 439c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator openFolderAnim = null; 440c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen final Runnable onCompleteRunnable; 441d794a3f46521b972fa02826d379d1efa112793d2Kenny Guy if (!Utilities.isLmpOrAbove()) { 442c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen positionAndSizeAsIcon(); 443c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen centerAboutIcon(); 444c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 445c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1); 446c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f); 447c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f); 448c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen final ObjectAnimator oa = 449c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 450c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen oa.setDuration(mExpandDuration); 451c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim = oa; 452c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 453c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setLayerType(LAYER_TYPE_HARDWARE, null); 454c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable = new Runnable() { 455c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen @Override 456c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void run() { 457c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setLayerType(LAYER_TYPE_NONE, null); 458c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 459c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen }; 460c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } else { 461c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen prepareReveal(); 462c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen centerAboutIcon(); 463c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 464c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 465c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int height = getFolderHeight(); 466c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 467c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float transX = - 0.075f * (width / 2 - getPivotX()); 468c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float transY = - 0.075f * (height / 2 - getPivotY()); 469c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setTranslationX(transX); 470c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen setTranslationY(transY); 471c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder tx = PropertyValuesHolder.ofFloat("translationX", transX, 0); 472c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen PropertyValuesHolder ty = PropertyValuesHolder.ofFloat("translationY", transY, 0); 473c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 474c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX()); 475c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY()); 476c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen float radius = (float) Math.sqrt(rx * rx + ry * ry); 477c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); 478c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator reveal = LauncherAnimUtils.createCircularReveal(this, (int) getPivotX(), 479c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen (int) getPivotY(), 0, radius); 480c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen reveal.setDuration(mMaterialExpandDuration); 481c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen reveal.setInterpolator(new LogDecelerateInterpolator(100, 0)); 482c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 483bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setAlpha(0f); 484bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal Animator iconsAlpha = LauncherAnimUtils.ofFloat(mContentWrapper, "alpha", 0f, 1f); 485c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setDuration(mMaterialExpandDuration); 486c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setStartDelay(mMaterialExpandStagger); 487c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 488c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 489290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.setAlpha(0f); 490290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal Animator textAlpha = LauncherAnimUtils.ofFloat(mFooter, "alpha", 0f, 1f); 491c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setDuration(mMaterialExpandDuration); 492c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setStartDelay(mMaterialExpandStagger); 493c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen textAlpha.setInterpolator(new AccelerateInterpolator(1.5f)); 494c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 495c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen Animator drift = LauncherAnimUtils.ofPropertyValuesHolder(this, tx, ty); 496c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setDuration(mMaterialExpandDuration); 497c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setStartDelay(mMaterialExpandStagger); 498c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen drift.setInterpolator(new LogDecelerateInterpolator(60, 0)); 499c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 500c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(drift); 501c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(iconsAlpha); 502c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(textAlpha); 503c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen anim.play(reveal); 504c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 505c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim = anim; 506c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 507bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setLayerType(LAYER_TYPE_HARDWARE, null); 508c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable = new Runnable() { 509c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen @Override 510c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen public void run() { 511bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContentWrapper.setLayerType(LAYER_TYPE_NONE, null); 512c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 513c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen }; 514c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 515c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim.addListener(new AnimatorListenerAdapter() { 516df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 517df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 5183371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 519bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.getAccessibilityDescription()); 520df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 521df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 522df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 523df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 5242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_OPEN; 525c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen 526c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen if (onCompleteRunnable != null) { 527c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen onCompleteRunnable.run(); 528c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen } 52955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 530bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.setFocusOnFirstChild(); 531df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 532df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 533c4fe9ea11e82fe16d60525323464fd50cf391378Adam Cohen openFolderAnim.start(); 53455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 53555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Make sure the folder picks up the last drag move even if the finger doesn't move. 53655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mDragController.isDragging()) { 53755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mDragController.forceTouchMove(); 53855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 53955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 54055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 54155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void beginExternalDrag(ShortcutInfo item) { 54255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mCurrentDragInfo = item; 5435d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mEmptyCellRank = mContent.allocateRankForNewItem(item); 54455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mIsExternalDrag = true; 54555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mDragInProgress = true; 5465d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal if (ALLOW_FOLDER_SCROLL && mPagedView.mIsSorted) { 5475d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.setOnAlarmListener(null); 5485d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.cancelAlarm(); 5495d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.setAlarm(SORTED_STICKY_REORDER_DELAY); 5505d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal } 5515d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal 552df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 553df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 5543371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen private void sendCustomAccessibilityEvent(int type, String text) { 5558b805b17158886035b38261eb611d8641701ae43Michael Jurka AccessibilityManager accessibilityManager = (AccessibilityManager) 5568b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); 5578b805b17158886035b38261eb611d8641701ae43Michael Jurka if (accessibilityManager.isEnabled()) { 5583371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen AccessibilityEvent event = AccessibilityEvent.obtain(type); 5593371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen onInitializeAccessibilityEvent(event); 5603371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen event.getText().add(text); 5618b805b17158886035b38261eb611d8641701ae43Michael Jurka accessibilityManager.sendAccessibilityEvent(event); 5623371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 5633371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen } 5643371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen 565df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void animateClosed() { 5668e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 567662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0); 568662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f); 569662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f); 570032e6bad1ba588ed8a884fb8f28fb8596efac480Michael Jurka final ObjectAnimator oa = 5712ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 572df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 5732801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.addListener(new AnimatorListenerAdapter() { 574df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 575df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 5762801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen onCloseComplete(); 5770121c3ea3d5bae176af193ea8ef23ae8a868dd31Michael Jurka setLayerType(LAYER_TYPE_NONE, null); 5782801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_SMALL; 579df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 580df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 581df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 5823371da0159cc54ff8ae1b1b26effb96445f208d5Adam Cohen sendCustomAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED, 5838b805b17158886035b38261eb611d8641701ae43Michael Jurka getContext().getString(R.string.folder_closed)); 584df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 585df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 586df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 5872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.setDuration(mExpandDuration); 5880121c3ea3d5bae176af193ea8ef23ae8a868dd31Michael Jurka setLayerType(LAYER_TYPE_HARDWARE, null); 589f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka oa.start(); 590df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 591df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 592cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public boolean acceptDrop(DragObject d) { 593cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen final ItemInfo item = (ItemInfo) d.dragInfo; 594df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen final int itemType = item.itemType; 5952801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || 5962801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && 5972801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen !isFull()); 598df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 599df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 600cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDragEnter(DragObject d) { 601c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mPrevTargetRank = -1; 602bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.cancelAlarm(); 6034846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (ALLOW_FOLDER_SCROLL) { 6044846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Get the area offset such that the folder only closes if half the drag icon width 6054846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // is outside the folder area 6064846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollAreaOffset = d.dragView.getDragRegionWidth() / 2 - d.xOffset; 6074846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 608df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 609df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 610bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mReorderAlarmListener = new OnAlarmListener() { 611bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 612c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.realTimeReorder(mEmptyCellRank, mTargetRank); 613c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mEmptyCellRank = mTargetRank; 614bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 615bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 616bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 617c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 6182374abfda3e53f84e005df8923170308e4df8c03Adam Cohen public boolean isLayoutRtl() { 6192374abfda3e53f84e005df8923170308e4df8c03Adam Cohen return (getLayoutDirection() == LAYOUT_DIRECTION_RTL); 6202374abfda3e53f84e005df8923170308e4df8c03Adam Cohen } 6212374abfda3e53f84e005df8923170308e4df8c03Adam Cohen 6224846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 623bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragOver(DragObject d) { 6244846193300245c8c0a1f9bde3175f273df044309Sunny Goyal onDragOver(d, REORDER_DELAY); 6254846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6264846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6274846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private int getTargetRank(DragObject d, float[] recycle) { 6284846193300245c8c0a1f9bde3175f273df044309Sunny Goyal recycle = d.getVisualCenter(recycle); 6294846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return mContent.findNearestArea( 6304846193300245c8c0a1f9bde3175f273df044309Sunny Goyal (int) recycle[0] - getPaddingLeft(), (int) recycle[1] - getPaddingTop()); 6314846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6324846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6334846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private void onDragOver(DragObject d, int reorderDelay) { 6344846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (ALLOW_FOLDER_SCROLL && mScrollPauseAlarm.alarmPending()) { 6354846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return; 6364846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6374846193300245c8c0a1f9bde3175f273df044309Sunny Goyal final float[] r = new float[2]; 6384846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mTargetRank = getTargetRank(d, r); 639f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 640c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal if (mTargetRank != mPrevTargetRank) { 6414cda5b770db7f375a4766fe6c0d657b9d5303374Alan Viverette mReorderAlarm.cancelAlarm(); 642c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal mReorderAlarm.setOnAlarmListener(mReorderAlarmListener); 643c46bfef5dfd8c6867641bdc32c27b03e2f183726Sunny Goyal mReorderAlarm.setAlarm(REORDER_DELAY); 644c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mPrevTargetRank = mTargetRank; 645bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 6464846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6474846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (!ALLOW_FOLDER_SCROLL) { 6484846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return; 6494846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6504846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6514846193300245c8c0a1f9bde3175f273df044309Sunny Goyal float x = r[0]; 6524846193300245c8c0a1f9bde3175f273df044309Sunny Goyal int currentPage = mPagedView.getNextPage(); 6534846193300245c8c0a1f9bde3175f273df044309Sunny Goyal int cellWidth = mPagedView.getCurrentCellLayout().getCellWidth(); 6544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (currentPage > 0 && x < cellWidth * ICON_OVERSCROLL_WIDTH_FACTOR) { 6554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Show scroll hint on the left 6564846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mScrollHintDir != DragController.SCROLL_LEFT) { 6574846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView.showScrollHint(-SCROLL_HINT_FRACTION); 6584846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_LEFT; 6594846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6604846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6614846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Set alarm for when the hint is complete 6624846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (!mOnScrollHintAlarm.alarmPending() || mCurrentScrollDir != DragController.SCROLL_LEFT) { 6634846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mCurrentScrollDir = DragController.SCROLL_LEFT; 6644846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.cancelAlarm(); 6654846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.setOnAlarmListener(new OnScrollHintListener(d)); 6664846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.setAlarm(SCROLL_HINT_DURATION); 6674846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6684846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mReorderAlarm.cancelAlarm(); 6694846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mTargetRank = mEmptyCellRank; 6704846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6714846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else if (currentPage < (mPagedView.getPageCount() - 1) && 6724846193300245c8c0a1f9bde3175f273df044309Sunny Goyal (x > (getWidth() - cellWidth * ICON_OVERSCROLL_WIDTH_FACTOR))) { 6734846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Show scroll hint on the right 6744846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mScrollHintDir != DragController.SCROLL_RIGHT) { 6754846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView.showScrollHint(SCROLL_HINT_FRACTION); 6764846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_RIGHT; 6774846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6784846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6794846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Set alarm for when the hint is complete 6804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (!mOnScrollHintAlarm.alarmPending() || mCurrentScrollDir != DragController.SCROLL_RIGHT) { 6814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mCurrentScrollDir = DragController.SCROLL_RIGHT; 6824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.cancelAlarm(); 6834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.setOnAlarmListener(new OnScrollHintListener(d)); 6844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.setAlarm(SCROLL_HINT_DURATION); 6854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 6864846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mReorderAlarm.cancelAlarm(); 6874846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mTargetRank = mEmptyCellRank; 6884846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6894846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else { 6904846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.cancelAlarm(); 6914846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mScrollHintDir != DragController.SCROLL_NONE) { 6924846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView.clearScrollHint(); 6934846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 6944846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 6954846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 696df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 697df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 698bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mOnExitAlarmListener = new OnAlarmListener() { 699bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 7003e8f811f31a2275e778244427271f77f4116c08bAdam Cohen completeDragExit(); 701bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 702bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 7032801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 70495bb800de9b0142bea0110b074eddbcf0e475736Adam Cohen public void completeDragExit() { 7053e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mLauncher.closeFolder(); 7063e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragInfo = null; 7073e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragView = null; 7083e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mSuppressOnAdd = false; 7093e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mRearrangeOnClose = true; 71055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mIsExternalDrag = false; 7113e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 7123e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 713bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragExit(DragObject d) { 71453b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini // We only close the folder if this is a true drag exit, ie. not because 71553b8d071ce63b2b55fa8bdc71488c44308bfcf2fMindy DelliCarpini // a drop has occurred above the folder. 716bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (!d.dragComplete) { 717bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setOnAlarmListener(mOnExitAlarmListener); 718bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY); 719bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 720bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mReorderAlarm.cancelAlarm(); 7214846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 7224846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (ALLOW_FOLDER_SCROLL) { 7234846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.cancelAlarm(); 7244846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.cancelAlarm(); 7254846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mScrollHintDir != DragController.SCROLL_NONE) { 7264846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView.clearScrollHint(); 7274846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 7284846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 7294846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 7302801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7312801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7321e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void onDropCompleted(final View target, final DragObject d, 7331e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka final boolean isFlingToDelete, final boolean success) { 7341e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (mDeferDropAfterUninstall) { 735f3007589e346df224d357b389069adfeb266545eMichael Jurka Log.d(TAG, "Deferred handling drop because waiting for uninstall."); 7361e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction = new Runnable() { 7371e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void run() { 7381e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka onDropCompleted(target, d, isFlingToDelete, success); 7391e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction = null; 7401e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7411e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka }; 7421e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka return; 7431e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7441e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 7451e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka boolean beingCalledAfterUninstall = mDeferredAction != null; 7461e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka boolean successfulDrop = 7471e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka success && (!beingCalledAfterUninstall || mUninstallSuccessful); 7485f8afe6280eae34620067696173e71943e1a30a3Winson Chung 7491e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (successfulDrop) { 75055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mDeleteFolderOnDropCompleted && !mItemAddedBackToSelfViaIcon && target != this) { 75167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen replaceFolderWithFinalItem(); 75267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 75367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } else { 754c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 75567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen // The drag failed, we need to return the item to the folder 75667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mFolderIcon.onDrop(d); 75767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 75867bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen 75967bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (target != this) { 76067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (mOnExitAlarm.alarmPending()) { 76167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mOnExitAlarm.cancelAlarm(); 7625455425c1b0355f5dd652cc8e7a2369c33dc9883Michael Jurka if (!successfulDrop) { 7637a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen mSuppressFolderDeletion = true; 7647a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 7655d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mScrollPauseAlarm.cancelAlarm(); 76667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen completeDragExit(); 76767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 7689c58d8269b3bdfdbe500b52ccce878ff2edb196bAdam Cohen } 7699c58d8269b3bdfdbe500b52ccce878ff2edb196bAdam Cohen 77067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDeleteFolderOnDropCompleted = false; 77167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDragInProgress = false; 77205e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = false; 773bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragInfo = null; 774bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = null; 775bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mSuppressOnAdd = false; 7764045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen 7774045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen // Reordering may have occured, and we need to save the new item locations. We do this once 7784045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen // at the end to prevent unnecessary database operations. 779f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen updateItemLocationsInDatabaseBatch(); 7804045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen } 7814045eb736e76374ec8b53b4cea2eaea47c72db4aAdam Cohen 7821e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void deferCompleteDropAfterUninstallActivity() { 7831e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferDropAfterUninstall = true; 7841e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7851e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 7861e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka public void onUninstallActivityReturned(boolean success) { 7871e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferDropAfterUninstall = false; 7881e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mUninstallSuccessful = success; 7891e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka if (mDeferredAction != null) { 7901e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka mDeferredAction.run(); 7911e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7921e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka } 7931e2f465f46ded990ea30516cdb7f0fcf3280411fMichael Jurka 794a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 795eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung public float getIntrinsicIconScaleFactor() { 796eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung return 1f; 797eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung } 798eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung 799eeb5bbc9409978cc2ae52d48380399fcde3d9f85Winson Chung @Override 800043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung public boolean supportsFlingToDelete() { 801043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung return true; 802043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung } 803043f2af567178b82b0b41f12d379e7dd12da2936Winson Chung 8041eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood @Override 8051eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood public boolean supportsAppInfoDropTarget() { 8061eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood return false; 8071eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood } 8081eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood 8091eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood @Override 8101eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood public boolean supportsDeleteDropTarget() { 8111eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood return true; 8121eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood } 8131eeb3fc9d874d98dfb43883d17efb4202d83d88aMathew Inwood 814a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onFlingToDelete(DragObject d, int x, int y, PointF vec) { 815a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // Do nothing 816a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 817a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 818a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung @Override 819a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung public void onFlingToDeleteCompleted() { 820a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung // Do nothing 821a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung } 822a48487a814c07a9f1f45eb3ffe3d873b3dc31b3bWinson Chung 823f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private void updateItemLocationsInDatabaseBatch() { 824f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<View> list = getItemsInReadingOrder(); 825f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ArrayList<ItemInfo> items = new ArrayList<ItemInfo>(); 826f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen for (int i = 0; i < list.size(); i++) { 827f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen View v = list.get(i); 828f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen ItemInfo info = (ItemInfo) v.getTag(); 82908f7261d11a53ae4b330ad4fa897b8519de3d750Sunny Goyal info.rank = i; 830f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen items.add(info); 831f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 832f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 833f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen LauncherModel.moveItemsInDatabase(mLauncher, items, mInfo.id, 0); 834f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 835f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 836e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen public void addItemLocationsInDatabase() { 837e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen ArrayList<View> list = getItemsInReadingOrder(); 838e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen for (int i = 0; i < list.size(); i++) { 839e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen View v = list.get(i); 840e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen ItemInfo info = (ItemInfo) v.getTag(); 841e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen LauncherModel.addItemToDatabase(mLauncher, info, mInfo.id, 0, 842e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen info.cellX, info.cellY, false); 843e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 844e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen } 845e25af795647a19f1a0d60bc4baea5a996d215fdfAdam Cohen 84667bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen public void notifyDrop() { 84767bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (mDragInProgress) { 84805e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen mItemAddedBackToSelfViaIcon = true; 84976078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 850df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 851df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 852df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public boolean isDropEnabled() { 853df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return true; 854df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 855df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 8562801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen public boolean isFull() { 857c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return mContent.isFull(); 8582801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 8592801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 8602801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void centerAboutIcon() { 8618e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 8622801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 863892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer); 8642801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 865f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen int height = getFolderHeight(); 8668e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen 867c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, sTempRect); 8682801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 869af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 870af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 871af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung 872c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int centerX = (int) (sTempRect.left + sTempRect.width() * scale / 2); 873c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int centerY = (int) (sTempRect.top + sTempRect.height() * scale / 2); 8742801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredLeft = centerX - width / 2; 8752801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredTop = centerY - height / 2; 8763057b1c259dafc555ff1eec32a9d2f7f81bb0bdaWinson Chung int currentPage = mLauncher.getWorkspace().getNextPage(); 8777cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // In case the workspace is scrolling, we need to use the final scroll to compute 8787cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // the folders bounds. 8797cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen mLauncher.getWorkspace().setFinalScrollForPageChange(currentPage); 88035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We first fetch the currently visible CellLayoutChildren 8817cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage); 882a52570f8f9ad65b85e33a2f2e87722f9edd6c6f4Michael Jurka ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets(); 88335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen Rect bounds = new Rect(); 88435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen parent.getDescendantRectRelativeToSelf(boundingLayout, bounds); 8857cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen // We reset the workspaces scroll 8867cc1bc4b657630250515ee8b1f65b77417e4c9b3Adam Cohen mLauncher.getWorkspace().resetFinalScrollForPageChange(currentPage); 88735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 88835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We need to bound the folder to the currently visible CellLayoutChildren 88935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int left = Math.min(Math.max(bounds.left, centeredLeft), 89035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.left + bounds.width() - width); 89135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int top = Math.min(Math.max(bounds.top, centeredTop), 89235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.top + bounds.height() - height); 893af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung if (grid.isPhone() && (grid.availableWidthPx - width) < grid.iconSizePx) { 894af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung // Center the folder if it is full (on phones only) 895af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung left = (grid.availableWidthPx - width) / 2; 896af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung } else if (width >= bounds.width()) { 897af40f205d7f0c5f73a92ff5d9b8e9602dbde58c0Winson Chung // If the folder doesn't fit within the bounds, center it about the desired bounds 89835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen left = bounds.left + (bounds.width() - width) / 2; 89935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 90035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen if (height >= bounds.height()) { 90135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen top = bounds.top + (bounds.height() - height) / 2; 9020e4857c302da6adbd45231d7a8bae0289fa33250Adam Cohen } 9032801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 9042801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotX = width / 2 + (centeredLeft - left); 9052801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotY = height / 2 + (centeredTop - top); 9062801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotX(folderPivotX); 9072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotY(folderPivotY); 908268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * 9092801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotX / width)); 910268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * 9112801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotY / height)); 9123bf84d3250bf45f2a5b041245e9bd327e03e22c0Adam Cohen 913662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.width = width; 914662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.height = height; 915662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.x = left; 916662b598c86a1772d95303ef9c921d4bbe342387bAdam Cohen lp.y = top; 9172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 9182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 919268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen float getPivotXForIconAnimation() { 920268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen return mFolderIconPivotX; 921268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen } 922268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen float getPivotYForIconAnimation() { 923268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen return mFolderIconPivotY; 924268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen } 925268c4751b547e1470a94030af73a4e7bb8ea221eAdam Cohen 926892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung private int getContentAreaHeight() { 927892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung LauncherAppState app = LauncherAppState.getInstance(); 928892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung DeviceProfile grid = app.getDynamicGrid().getDeviceProfile(); 929892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung Rect workspacePadding = grid.getWorkspacePadding(grid.isLandscape ? 930892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung CellLayout.LANDSCAPE : CellLayout.PORTRAIT); 931892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung int maxContentAreaHeight = grid.availableHeightPx - 932892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung workspacePadding.top - workspacePadding.bottom - 933290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooterHeight; 9341960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen int height = Math.min(maxContentAreaHeight, 935892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung mContent.getDesiredHeight()); 9361960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen return Math.max(height, MIN_CONTENT_DIMEN); 9371960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen } 9381960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen 9391960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen private int getContentAreaWidth() { 9401960ea4a7102bd0fa03cad1ea1e3a91f8e1bd9cdAdam Cohen return Math.max(mContent.getDesiredWidth(), MIN_CONTENT_DIMEN); 941892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung } 942892c74d460ad98c6306420e1127c9aa3e505ba25Winson Chung 943f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen private int getFolderHeight() { 944c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return getFolderHeight(getContentAreaHeight()); 945c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 946c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 947c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal private int getFolderHeight(int contentAreaHeight) { 948290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal return getPaddingTop() + getPaddingBottom() + contentAreaHeight + mFooterHeight; 949f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen } 950f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen 951f0f4eda31841f41d892bf18847c1acdc45d2cd64Adam Cohen protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 952c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentWidth = getContentAreaWidth(); 953c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentHeight = getContentAreaHeight(); 9542801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 955c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(contentWidth, MeasureSpec.EXACTLY); 956c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY); 957c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 958c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.setFixedSize(contentWidth, contentHeight); 959c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContentWrapper.measure(contentAreaWidthSpec, contentAreaHeightSpec); 960290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mFooter.measure(contentAreaWidthSpec, 961290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal MeasureSpec.makeMeasureSpec(mFooterHeight, MeasureSpec.EXACTLY)); 962c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 963c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int folderWidth = getPaddingLeft() + getPaddingRight() + contentWidth; 964c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal int folderHeight = getFolderHeight(contentHeight); 965c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal setMeasuredDimension(folderWidth, folderHeight); 966c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 967c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 968c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 969c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * Rearranges the children based on their rank. 970c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 971c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void rearrangeChildren() { 972c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(-1); 973c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal } 974c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal 975c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal /** 976c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * Rearranges the children based on their rank. 977c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * @param itemCount if greater than the total children count, empty spaces are left at the end, 978c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal * otherwise it is ignored. 979c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal */ 980c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal public void rearrangeChildren(int itemCount) { 981c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal ArrayList<View> views = getItemsInReadingOrder(); 982c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.arrangeChildren(views, Math.max(itemCount, views.size())); 9837c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 9842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 9852801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 986c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal // TODO remove this once GSA code fix is submitted 987c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal public ViewGroup getContent() { 988c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal return (ViewGroup) mContent; 989c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal } 990c4918358049914a4700bc8f2eb91167eb4a67becSunny Goyal 991a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public int getItemCount() { 992c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal return mContent.getItemCount(); 993a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 994a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 9952801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void onCloseComplete() { 99605e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen DragLayer parent = (DragLayer) getParent(); 9975649c287039ea7908112b41604c3fc2893c4697eMichael Jurka if (parent != null) { 9985649c287039ea7908112b41604c3fc2893c4697eMichael Jurka parent.removeView(this); 9995649c287039ea7908112b41604c3fc2893c4697eMichael Jurka } 10004554ee16f122a3dbd9a8d3b828f1c8c7e7b7fe99Adam Cohen mDragController.removeDropTarget((DropTarget) this); 100105e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen clearFocus(); 1002ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderIcon.requestFocus(); 100305e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen 10042801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mRearrangeOnClose) { 1005c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 10062801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = false; 10072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1008afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 100967bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen if (!mDragInProgress && !mSuppressFolderDeletion) { 101067bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen replaceFolderWithFinalItem(); 101167bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } else if (mDragInProgress) { 101267bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mDeleteFolderOnDropCompleted = true; 101367bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen } 1014afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 101567bd9ccf856840856944815a382e4bbb0e71e949Adam Cohen mSuppressFolderDeletion = false; 1016afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1017afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 1018afb01ee74243cede19088e694ca82cea5983c603Adam Cohen private void replaceFolderWithFinalItem() { 1019fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // Add the last remaining child to the workspace in place of the folder 1020fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen Runnable onCompleteRunnable = new Runnable() { 1021fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen @Override 1022fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen public void run() { 1023dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screenId); 1024fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen 102533231f587e1a6f716af68e6198df774d2847a8e5Winson Chung View child = null; 1026fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen // Move the item from the folder to the workspace, in the position of the folder 1027fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen if (getItemCount() == 1) { 1028fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen ShortcutInfo finalItem = mInfo.contents.get(0); 1029c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen child = mLauncher.createShortcut(R.layout.application, cellLayout, 1030fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen finalItem); 1031fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container, 1032dcd297f05a866e07090d6e2af8fb4b15f28cb555Adam Cohen mInfo.screenId, mInfo.cellX, mInfo.cellY); 1033fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1034487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (getItemCount() <= 1) { 1035487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen // Remove the folder 1036487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, mInfo); 10370eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler if (cellLayout != null) { 10380eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler // b/12446428 -- sometimes the cell layout has already gone away? 10390eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler cellLayout.removeView(mFolderIcon); 10400eb687fdc431e7eae4e8f2f4d5dd3a6e48779008Dan Sandler } 1041487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen if (mFolderIcon instanceof DropTarget) { 1042487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mDragController.removeDropTarget((DropTarget) mFolderIcon); 1043487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1044487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen mLauncher.removeFolder(mInfo); 1045487f7dd3059621527eb439d7d51d34e00293f9b1Adam Cohen } 1046c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen // We add the child after removing the folder to prevent both from existing at 10470e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung // the same time in the CellLayout. We need to add the new item with addInScreenFromBind() 10480e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung // to ensure that hotseat items are placed correctly. 1049c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen if (child != null) { 10500e6a713fca3261021fcaca62c75dad8486c5e39fWinson Chung mLauncher.getWorkspace().addInScreenFromBind(child, mInfo.container, mInfo.screenId, 1051c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen mInfo.cellX, mInfo.cellY, mInfo.spanX, mInfo.spanY); 1052c5e63f3dc7f19d0da8380e425894450302700ab9Adam Cohen } 1053fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1054fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen }; 1055bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View finalChild = mContent.getLastItem(); 1056fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen if (finalChild != null) { 1057fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen mFolderIcon.performDestroyAnimation(finalChild, onCompleteRunnable); 105833231f587e1a6f716af68e6198df774d2847a8e5Winson Chung } else { 105933231f587e1a6f716af68e6198df774d2847a8e5Winson Chung onCompleteRunnable.run(); 1060afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1061fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen mDestroyed = true; 1062fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen } 1063afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 1064fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen boolean isDestroyed() { 1065fb91f303f5e672f9b4c4f9f8a03486b224d60cd6Adam Cohen return mDestroyed; 10662801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 10672801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 1068ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // This method keeps track of the last item in the folder for the purposes 1069ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen // of keyboard focus 1070290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal public void updateTextViewFocus() { 1071bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View lastChild = mContent.getLastItem(); 1072ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen if (lastChild != null) { 1073ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusDownId(lastChild.getId()); 1074ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusRightId(lastChild.getId()); 1075ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusLeftId(lastChild.getId()); 1076ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen mFolderName.setNextFocusUpId(lastChild.getId()); 1077ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen } 1078ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen } 1079ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 1080bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDrop(DragObject d) { 108155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi Runnable cleanUpRunnable = null; 108255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 1083689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen // If we are coming from All Apps space, we defer removing the extra empty screen 1084689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen // until the folder closes 108555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (d.dragSource != mLauncher.getWorkspace() && !(d.dragSource instanceof Folder)) { 108655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi cleanUpRunnable = new Runnable() { 108755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi @Override 108855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi public void run() { 1089689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen mLauncher.exitSpringLoadedDragModeDelayed(true, 1090689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, 1091689ff16ea27fb7c22c247aaf4f42ffe42fede253Adam Cohen null); 109255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 109355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi }; 1094bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 109555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 10964846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (ALLOW_FOLDER_SCROLL) { 10974846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // If the icon was dropped while the page was being scrolled, we need to compute 10984846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // the target location again such that the icon is placed of the final page. 10994846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (!mPagedView.rankOnCurrentPage(mEmptyCellRank)) { 11004846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Reorder again. 11014846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mTargetRank = getTargetRank(d, null); 11024846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 11034846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Rearrange items immediately. 11044846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mReorderAlarmListener.onAlarm(mReorderAlarm); 11054846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 11064846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mOnScrollHintAlarm.cancelAlarm(); 11074846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.cancelAlarm(); 11084846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 11094846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView.completePendingPageChanges(); 11104846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 11114846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 111255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi View currentDragView; 111355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi ShortcutInfo si = mCurrentDragInfo; 111455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (mIsExternalDrag) { 1115c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal currentDragView = mContent.createAndAddViewForRank(si, mEmptyCellRank); 111695abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // Actually move the item in the database if it was an external drag. Call this 111795abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // before creating the view, so that ShortcutInfo is updated appropriately. 111895abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal LauncherModel.addOrMoveItemInDatabase( 111995abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal mLauncher, si, mInfo.id, 0, si.cellX, si.cellY); 112095abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal 112195abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal // We only need to update the locations if it doesn't get handled in #onDropCompleted. 112295abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal if (d.dragSource != this) { 112395abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal updateItemLocationsInDatabaseBatch(); 112495abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal } 112595abbb330ce9bbaf23594245f0f8a795c8118038Sunny Goyal mIsExternalDrag = false; 112655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 112755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi currentDragView = mCurrentDragView; 1128c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal mContent.addViewForRank(currentDragView, si, mEmptyCellRank); 112955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 113055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 113155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi if (d.dragView.hasDrawn()) { 113255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 113355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Temporarily reset the scale such that the animation target gets calculated correctly. 113455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi float scaleX = getScaleX(); 113555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi float scaleY = getScaleY(); 113655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleX(1.0f); 113755bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleY(1.0f); 113855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, currentDragView, 113955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi cleanUpRunnable, null); 114055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleX(scaleX); 114155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi setScaleY(scaleY); 114255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } else { 114355bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi d.deferDragViewCleanupPostAnimation = false; 114455bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi currentDragView.setVisibility(VISIBLE); 114555bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi } 114655bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mItemsInvalidated = true; 1147c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 114855bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi 114955bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi // Temporarily suppress the listener, as we did all the work already here. 115055bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mSuppressOnAdd = true; 115155bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mInfo.add(si); 115255bd9725d5c0373b89f7b9bbd9547550ea3bbc63Jorim Jaggi mSuppressOnAdd = false; 11534b02017fa5bdb276347d0b9e8a76a9fdd5bb0eb9Sunny Goyal // Clear the drag info, as it is no longer being dragged. 11544b02017fa5bdb276347d0b9e8a76a9fdd5bb0eb9Sunny Goyal mCurrentDragInfo = null; 1155bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 1156bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 11577a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // This is used so the item doesn't immediately appear in the folder when added. In one case 11587a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // we need to create the illusion that the item isn't added back to the folder yet, to 11597a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen // to correspond to the animation of the icon back into the folder. This is 11607a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen public void hideItem(ShortcutInfo info) { 11617a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen View v = getViewForInfo(info); 11627a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen v.setVisibility(INVISIBLE); 11637a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 11647a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen public void showItem(ShortcutInfo info) { 11657a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen View v = getViewForInfo(info); 11667a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen v.setVisibility(VISIBLE); 11677a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen } 11687a8b82b5926e6a520df28e7f591b9a94ec605581Adam Cohen 1169bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAdd(ShortcutInfo item) { 1170bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mItemsInvalidated = true; 117105e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // If the item was dropped onto this open folder, we have done the work associated 117205e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // with adding the item to the folder, as indicated by mSuppressOnAdd being set 1173bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (mSuppressOnAdd) return; 11745d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal mContent.createAndAddViewForRank(item, mContent.allocateRankForNewItem(item)); 1175bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen LauncherModel.addOrMoveItemInDatabase( 1176bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); 1177bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 1178bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 1179a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onRemove(ShortcutInfo item) { 11807c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 118105e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // If this item is being dragged from this open folder, we have already handled 118205e0f40e50574f50678a9e1461cb245cddc46abbAdam Cohen // the work associated with removing the item, so we don't have to do anything here. 1183bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (item == mCurrentDragInfo) return; 1184df1e4e868a1970b756486dadd652651d40276d36Adam Cohen View v = getViewForInfo(item); 1185290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal mContent.removeItem(v); 11862801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mState == STATE_ANIMATING) { 11872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = true; 11882801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 1189c3a609f950a713d995f1968574d8ed7b4449f415Sunny Goyal rearrangeChildren(); 11902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 1191afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 1192afb01ee74243cede19088e694ca82cea5983c603Adam Cohen replaceFolderWithFinalItem(); 1193afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 1194a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 11957c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen 1196bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal private View getViewForInfo(final ShortcutInfo item) { 1197bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return mContent.iterateOverItems(new ItemOperator() { 1198bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1199bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal @Override 1200bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal public boolean evaluate(ItemInfo info, View view, View parent) { 1201bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return info == item; 1202df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 1203bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal }); 1204df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 1205df1e4e868a1970b756486dadd652651d40276d36Adam Cohen 120676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen public void onItemsChanged() { 1207ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen updateTextViewFocus(); 120876078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 1209ac56cff1860b71d3f164aedd268703936e08fdc0Adam Cohen 121076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onTitleChanged(CharSequence title) { 121176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 121276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 12137c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen public ArrayList<View> getItemsInReadingOrder() { 12147c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (mItemsInvalidated) { 12157c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInReadingOrder.clear(); 1216bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mContent.iterateOverItems(new ItemOperator() { 1217bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1218bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal @Override 1219bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal public boolean evaluate(ItemInfo info, View view, View parent) { 1220bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal mItemsInReadingOrder.add(view); 1221bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal return false; 12227c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 1223bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal }); 12247c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = false; 12257c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 12267c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen return mItemsInReadingOrder; 12277c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 12288dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 12298dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void getLocationInDragLayer(int[] loc) { 12308dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mLauncher.getDragLayer().getLocationInDragLayer(this, loc); 12318dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 1232ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen 1233ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen public void onFocusChange(View v, boolean hasFocus) { 1234ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen if (v == mFolderName && hasFocus) { 1235ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen startEditingFolderName(); 1236ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen } 1237ea0818d475df26d498ce08105bc2bc5582fce5a9Adam Cohen } 12387d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen 12397d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen @Override 12407d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen public void getHitRectRelativeToDragLayer(Rect outRect) { 12417d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen getHitRect(outRect); 12424846193300245c8c0a1f9bde3175f273df044309Sunny Goyal outRect.left -= mScrollAreaOffset; 12434846193300245c8c0a1f9bde3175f273df044309Sunny Goyal outRect.right += mScrollAreaOffset; 12444846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12454846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12464846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private class OnScrollHintListener implements OnAlarmListener { 12474846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12484846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private final DragObject mDragObject; 12494846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12504846193300245c8c0a1f9bde3175f273df044309Sunny Goyal OnScrollHintListener(DragObject object) { 12514846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mDragObject = object; 12524846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12534846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12544846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 12554846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Scroll hint has been shown long enough. Now scroll to appropriate page. 12564846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 12574846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 12584846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void onAlarm(Alarm alarm) { 12594846193300245c8c0a1f9bde3175f273df044309Sunny Goyal if (mCurrentScrollDir == DragController.SCROLL_LEFT) { 12604846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView.scrollLeft(); 12614846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 12624846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else if (mCurrentScrollDir == DragController.SCROLL_RIGHT) { 12634846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mPagedView.scrollRight(); 12644846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollHintDir = DragController.SCROLL_NONE; 12654846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } else { 12664846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // This should not happen 12674846193300245c8c0a1f9bde3175f273df044309Sunny Goyal return; 12684846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12694846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mCurrentScrollDir = DragController.SCROLL_NONE; 12704846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12714846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Pause drag event until the scrolling is finished 12724846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.setOnAlarmListener(new OnScrollFinishedListener(mDragObject)); 12734846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mScrollPauseAlarm.setAlarm(DragController.RESCROLL_DELAY); 12744846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12754846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12764846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12774846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private class OnScrollFinishedListener implements OnAlarmListener { 12784846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12794846193300245c8c0a1f9bde3175f273df044309Sunny Goyal private final DragObject mDragObject; 12804846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12814846193300245c8c0a1f9bde3175f273df044309Sunny Goyal OnScrollFinishedListener(DragObject object) { 12824846193300245c8c0a1f9bde3175f273df044309Sunny Goyal mDragObject = object; 12834846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12844846193300245c8c0a1f9bde3175f273df044309Sunny Goyal 12854846193300245c8c0a1f9bde3175f273df044309Sunny Goyal /** 12864846193300245c8c0a1f9bde3175f273df044309Sunny Goyal * Page scroll is complete. 12874846193300245c8c0a1f9bde3175f273df044309Sunny Goyal */ 12884846193300245c8c0a1f9bde3175f273df044309Sunny Goyal @Override 12894846193300245c8c0a1f9bde3175f273df044309Sunny Goyal public void onAlarm(Alarm alarm) { 12904846193300245c8c0a1f9bde3175f273df044309Sunny Goyal // Reorder immediately on page change. 12914846193300245c8c0a1f9bde3175f273df044309Sunny Goyal onDragOver(mDragObject, 1); 12924846193300245c8c0a1f9bde3175f273df044309Sunny Goyal } 12937d30a37007bac318db1c9af47a9af12d348042a5Adam Cohen } 1294bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1295bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal public static interface FolderContent { 1296bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal void setFolder(Folder f); 1297bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1298290800b5b7d575fd709f244f54a5fa5b63b58876Sunny Goyal void removeItem(View v); 1299bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1300bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal boolean isFull(); 1301bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal int getItemCount(); 1302bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1303bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal int getDesiredWidth(); 1304bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal int getDesiredHeight(); 1305bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal void setFixedSize(int width, int height); 1306bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1307bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 1308bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * Iterates over all its items in a reading order. 1309bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * @return the view for which the operator returned true. 1310bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 1311bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View iterateOverItems(ItemOperator op); 1312bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View getLastItem(); 1313bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1314bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal String getAccessibilityDescription(); 1315bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1316bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 1317bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * Binds items to the layout. 1318bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * @return list of items that could not be bound, probably because we hit the max size limit. 1319bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 1320bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal ArrayList<ShortcutInfo> bindItems(ArrayList<ShortcutInfo> children); 1321bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1322bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 13235d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal * Create space for a new item, and returns the rank for that item. 1324bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * Resizes the content if necessary. 1325bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 13265d85c44fd873c740dc191b28424c2ee367d730a2Sunny Goyal int allocateRankForNewItem(ShortcutInfo info); 1327bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1328bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal View createAndAddViewForRank(ShortcutInfo item, int rank); 1329bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1330bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 1331bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * Adds the {@param view} to the layout based on {@param rank} and updated the position 1332bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * related attributes. It assumes that {@param item} is already attached to the view. 1333bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 1334bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal void addViewForRank(View view, ShortcutInfo item, int rank); 1335bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1336bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 1337bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * Reorders the items such that the {@param empty} spot moves to {@param target} 1338bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 1339bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal void realTimeReorder(int empty, int target); 1340bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1341bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 1342bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * @return the rank of the cell nearest to the provided pixel position. 1343bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 1344bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal int findNearestArea(int pixelX, int pixelY); 1345bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1346bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 1347bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * Updates position and rank of all the children in the view based. 1348bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * @param list the ordered list of children. 1349bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * @param itemCount if greater than the total children count, empty spaces are left 1350bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * at the end. 1351bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 1352bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal void arrangeChildren(ArrayList<View> list, int itemCount); 1353bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal 1354bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal /** 1355bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal * Sets the focus on the first visible child. 1356bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal */ 1357bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal void setFocusOnFirstChild(); 1358bc753359f8b08e0813016eebc8392b83a4d2bd6eSunny Goyal } 135931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1360