Folder.java revision e601a43345224e3e386abc68bbea8b08b2df9570
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/* 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2; 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.Animator; 20df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.AnimatorListenerAdapter; 21df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.ObjectAnimator; 22df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.PropertyValuesHolder; 23df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.ValueAnimator; 24df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.animation.ValueAnimator.AnimatorUpdateListener; 2531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 2676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.content.res.Resources; 27fb5411e98278d461b78aea0663d3e85f7a9e8a15Romain Guyimport android.graphics.Rect; 28badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohenimport android.graphics.drawable.Drawable; 297a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohenimport android.text.InputType; 30e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohenimport android.text.Selection; 31e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohenimport android.text.Spannable; 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 3376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.ActionMode; 3476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.KeyEvent; 35df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.view.LayoutInflater; 3676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.Menu; 3776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.MenuItem; 380c872ba544ecfd9b106bb66137da8680927590deAdam Cohenimport android.view.MotionEvent; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View; 402801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.view.animation.AccelerateInterpolator; 412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohenimport android.view.animation.DecelerateInterpolator; 4276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.inputmethod.EditorInfo; 4376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohenimport android.view.inputmethod.InputMethodManager; 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.widget.LinearLayout; 45df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohenimport android.widget.TextView; 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 47edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guyimport com.android.launcher.R; 48a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohenimport com.android.launcher2.FolderInfo.FolderListener; 49edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 50c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohenimport java.util.ArrayList; 51c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen 5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 5331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Represents a set of icons chosen by the user or generated by the system. 5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 558dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohenpublic class Folder extends LinearLayout implements DragSource, View.OnClickListener, 568dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen View.OnLongClickListener, DropTarget, FolderListener, TextView.OnEditorActionListener { 5731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 584eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen private static final String TAG = "Launcher.Folder"; 59df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 604eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen protected DragController mDragController; 6131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected Launcher mLauncher; 6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected FolderInfo mInfo; 6331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 64df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_NONE = -1; 65df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_SMALL = 0; 66df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_ANIMATING = 1; 67df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static final int STATE_OPEN = 2; 68df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 69df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private int mExpandDuration; 70df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen protected CellLayout mContent; 71df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private final LayoutInflater mInflater; 72df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private final IconCache mIconCache; 73df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private int mState = STATE_NONE; 742801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private static final int FULL_GROW = 0; 752801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private static final int PARTIAL_GROW = 1; 76bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private static final int REORDER_ANIMATION_DURATION = 230; 77bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private static final int ON_EXIT_CLOSE_DELAY = 800; 782801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private int mMode = PARTIAL_GROW; 792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private boolean mRearrangeOnClose = false; 802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private FolderIcon mFolderIcon; 812801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private int mMaxCountX; 822801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private int mMaxCountY; 832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private Rect mNewSize = new Rect(); 843e8f811f31a2275e778244427271f77f4116c08bAdam Cohen private Rect mIconRect = new Rect(); 857c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen private ArrayList<View> mItemsInReadingOrder = new ArrayList<View>(); 86badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen private Drawable mIconDrawable; 877c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen boolean mItemsInvalidated = false; 88bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private ShortcutInfo mCurrentDragInfo; 89bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private View mCurrentDragView; 90bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen boolean mSuppressOnAdd = false; 91bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private int[] mTargetCell = new int[2]; 92bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private int[] mPreviousTargetCell = new int[2]; 93bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private int[] mEmptyCell = new int[2]; 94ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen private int[] mTempXY = new int[2]; 95bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private Alarm mReorderAlarm = new Alarm(); 96bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private Alarm mOnExitAlarm = new Alarm(); 9776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private TextView mFolderName; 9876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private int mFolderNameHeight; 994ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen private Rect mHitRect = new Rect(); 1008e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen private Rect mTempRect = new Rect(); 1018dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen private boolean mFirstOpen = true; 10276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 10376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private boolean mIsEditingName = false; 10476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private InputMethodManager mInputMethodManager; 105df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 106a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen private static String sDefaultFolderName; 107a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen private static String sHintText; 108a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen 10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 11231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 11331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param attrs The attribtues set containing the Workspace's customization values. 11431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Folder(Context context, AttributeSet attrs) { 11631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs); 11731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project setAlwaysDrawnWithCacheEnabled(false); 118df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mInflater = LayoutInflater.from(context); 119df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mIconCache = ((LauncherApplication)context.getApplicationContext()).getIconCache(); 1208e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen mMaxCountX = LauncherModel.getCellCountX(); 1218e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen mMaxCountY = LauncherModel.getCellCountY(); 12276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 12376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager = (InputMethodManager) 12476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 12576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 12676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen Resources res = getResources(); 12776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mExpandDuration = res.getInteger(R.integer.config_folderAnimDuration); 1284ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 1294ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen if (sDefaultFolderName == null) { 1304ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen sDefaultFolderName = res.getString(R.string.folder_name); 1314ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 132a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen if (sHintText == null) { 133a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen sHintText = res.getString(R.string.folder_hint_text); 134a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen } 1354eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen 1364eac29a80b9a73465c8de54f1caec2a8098a73c6Adam Cohen mLauncher = (Launcher) context; 13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected void onFinishInflate() { 14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.onFinishInflate(); 142df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mContent = (CellLayout) findViewById(R.id.folder_content); 1432801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mContent.setGridSize(0, 0); 14476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName = (TextView) findViewById(R.id.folder_name); 14576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 14676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen // We find out how tall the text view wants to be (it is set to wrap_content), so that 14776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen // we can allocate the appropriate amount of space for it. 14876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen int measureSpec = MeasureSpec.UNSPECIFIED; 14976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.measure(measureSpec, measureSpec); 15076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderNameHeight = mFolderName.getMeasuredHeight(); 15176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 15276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen // We disable action mode for now since it messes up the view on phones 15376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback); 15476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setCursorVisible(false); 15576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setOnEditorActionListener(this); 1564ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setSelectAllOnFocus(true); 1577a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen mFolderName.setInputType(mFolderName.getInputType() | 1587a14d0bddea652ddca855af0c413e47a6c1360b2Adam Cohen InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS); 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1602801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 16176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { 16276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 16376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 16476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 16576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 16676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onCreateActionMode(ActionMode mode, Menu menu) { 16776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 16876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 16976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 17076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onDestroyActionMode(ActionMode mode) { 17176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 17276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 17376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 17476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 17576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 17676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen }; 17776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onClick(View v) { 179df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 180df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 181df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen // refactor this code from Folder 182df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ShortcutInfo item = (ShortcutInfo) tag; 183df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen int[] pos = new int[2]; 184df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen v.getLocationOnScreen(pos); 185df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen item.intent.setSourceBounds(new Rect(pos[0], pos[1], 186df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen pos[0] + v.getWidth(), pos[1] + v.getHeight())); 187df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mLauncher.startActivitySafely(item.intent, item); 188df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 19031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onInterceptTouchEvent(MotionEvent ev) { 19276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (ev.getAction() == MotionEvent.ACTION_DOWN) { 19376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.getHitRect(mHitRect); 19476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (mHitRect.contains((int) ev.getX(), (int) ev.getY()) && !mIsEditingName) { 19576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen startEditingFolderName(); 19676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 19776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 19876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 19976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 20076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 20131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onLongClick(View v) { 202df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen Object tag = v.getTag(); 203df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (tag instanceof ShortcutInfo) { 204df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ShortcutInfo item = (ShortcutInfo) tag; 205df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (!v.isInTouchMode()) { 206df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return false; 207df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 208df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 209df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mLauncher.getWorkspace().onDragStartedWithItem(v); 210ac8c87687b8e063c981f28cb31bab2cc110f26ccAdam Cohen mLauncher.getWorkspace().beginDragShared(v, this); 211badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen mIconDrawable = ((TextView) v).getCompoundDrawables()[1]; 21276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 21376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen mCurrentDragInfo = item; 214bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mEmptyCell[0] = item.cellX; 215bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mEmptyCell[1] = item.cellY; 216bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = v; 217fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen 218fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mContent.removeView(mCurrentDragView); 219fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mInfo.remove(mCurrentDragInfo); 220df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return true; 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean isEditingName() { 22576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mIsEditingName; 22676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 22776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 22876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void startEditingFolderName() { 229a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(""); 23076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setCursorVisible(true); 23176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = true; 23276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 23376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 23476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void dismissEditingName() { 23576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); 23676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen doneEditingFolderName(true); 23776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 23876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 23976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void doneEditingFolderName(boolean commit) { 240a65beeea13c18c443f15f8d51c4c6e153a6c4ef9Adam Cohen mFolderName.setHint(sHintText); 24176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mInfo.setTitle(mFolderName.getText()); 24276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen LauncherModel.updateItemInDatabase(mLauncher, mInfo); 24376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.setCursorVisible(false); 24476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mFolderName.clearFocus(); 245e601a43345224e3e386abc68bbea8b08b2df9570Adam Cohen Selection.setSelection((Spannable) mFolderName.getText(), 0, 0); 24676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen mIsEditingName = false; 24776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 24876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 24976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { 25076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen if (actionId == EditorInfo.IME_ACTION_DONE) { 25176fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen dismissEditingName(); 25276fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return true; 25376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 25476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return false; 25576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 25676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 25776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public View getEditTextRegion() { 25876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen return mFolderName; 25976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 26076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen 261badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen public Drawable getDragDrawable() { 262badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen return mIconDrawable; 263badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen } 264badf71e11fba2d6efa1d1bcca9542001f90a3777Adam Cohen 2650c872ba544ecfd9b106bb66137da8680927590deAdam Cohen /** 2660c872ba544ecfd9b106bb66137da8680927590deAdam Cohen * We need to handle touch events to prevent them from falling through to the workspace below. 2670c872ba544ecfd9b106bb66137da8680927590deAdam Cohen */ 2680c872ba544ecfd9b106bb66137da8680927590deAdam Cohen @Override 2690c872ba544ecfd9b106bb66137da8680927590deAdam Cohen public boolean onTouchEvent(MotionEvent ev) { 2700c872ba544ecfd9b106bb66137da8680927590deAdam Cohen return true; 2710c872ba544ecfd9b106bb66137da8680927590deAdam Cohen } 2720c872ba544ecfd9b106bb66137da8680927590deAdam Cohen 27300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragController(DragController dragController) { 27400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = dragController; 27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2772801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen void setFolderIcon(FolderIcon icon) { 2782801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mFolderIcon = icon; 2792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 2802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return the FolderInfo object associated with this folder 28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 28431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project FolderInfo getInfo() { 28531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mInfo; 28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void onOpen() { 289df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen // When the folder opens, we need to refresh the GridView's selection by 290df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen // forcing a layout 291df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen // TODO: find out if this is still necessary 292df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mContent.requestLayout(); 29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void onClose() { 2968e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer parent = (DragLayer) getParent(); 2978e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen parent.removeView(Folder.this); 29876fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen clearFocus(); 29931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void bind(FolderInfo info) { 30231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mInfo = info; 303df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ArrayList<ShortcutInfo> children = info.contents; 304c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>(); 3057c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen setupContentForNumItems(children.size()); 306df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen for (int i = 0; i < children.size(); i++) { 307df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen ShortcutInfo child = (ShortcutInfo) children.get(i); 308c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen if (!createAndAddShortcut(child)) { 309c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen overflow.add(child); 310c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen } 311df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 312c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 313c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // If our folder has too many items we prune them from the list. This is an issue 314c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // when upgrading from the old Folders implementation which could contain an unlimited 315c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // number of items. 316c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen for (ShortcutInfo item: overflow) { 317c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen mInfo.remove(item); 318c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, item); 319c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen } 320c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 3214dbe6d993485a702505ee4895db94aaa89655f2cAdam Cohen mItemsInvalidated = true; 322a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen mInfo.addListener(this); 3234ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen 324afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (!sDefaultFolderName.contentEquals(mInfo.title)) { 3254ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(mInfo.title); 3264ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } else { 3274ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen mFolderName.setText(""); 3284ef610fc88e447ff6d6cdd382a7d064be9f739d6Adam Cohen } 329df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 330df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 331df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 332df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * Creates a new UserFolder, inflated from R.layout.user_folder. 333df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 334df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @param context The application's context. 335df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * 336df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * @return A new UserFolder. 337df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 338df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen static Folder fromXml(Context context) { 339df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return (Folder) LayoutInflater.from(context).inflate(R.layout.user_folder, null); 340df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 341df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 342df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen /** 343df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * This method is intended to make the UserFolder to be visually identical in size and position 344df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen * to its associated FolderIcon. This allows for a seamless transition into the expanded state. 345df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen */ 346df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen private void positionAndSizeAsIcon() { 3473e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (!(getParent() instanceof DragLayer)) return; 348df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 3498e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 350df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 3512801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mMode == PARTIAL_GROW) { 3522801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setScaleX(0.8f); 3532801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setScaleY(0.8f); 3542801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setAlpha(0f); 3552801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 3563e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mLauncher.getDragLayer().getDescendantRectRelativeToSelf(mFolderIcon, mIconRect); 3573e8f811f31a2275e778244427271f77f4116c08bAdam Cohen lp.width = mIconRect.width(); 3583e8f811f31a2275e778244427271f77f4116c08bAdam Cohen lp.height = mIconRect.height(); 3593e8f811f31a2275e778244427271f77f4116c08bAdam Cohen lp.x = mIconRect.left; 3603e8f811f31a2275e778244427271f77f4116c08bAdam Cohen lp.y = mIconRect.top; 3612801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mContent.setAlpha(0); 3622801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 363df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_SMALL; 364df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 365df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 366df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void animateOpen() { 3678dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen if (mFirstOpen) { 3688dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen setLayerType(LAYER_TYPE_HARDWARE, null); 3698dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen buildLayer(); 3708dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mFirstOpen = false; 3718dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 3728dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 3733e8f811f31a2275e778244427271f77f4116c08bAdam Cohen positionAndSizeAsIcon(); 3743e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 3758e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 376df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 3772801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen ObjectAnimator oa; 3788e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 379df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 3802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen centerAboutIcon(); 3812801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mMode == PARTIAL_GROW) { 3822801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1); 3832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f); 3842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f); 3852801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 3862801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 3872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mNewSize.width()); 3882801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mNewSize.height()); 3892801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", mNewSize.left); 3902801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", mNewSize.top); 3912801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y); 3922801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.addUpdateListener(new AnimatorUpdateListener() { 3932801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 3942801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen requestLayout(); 3952801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 3962801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen }); 3972801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 3982801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f); 3992801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha); 4002801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen alphaOa.setDuration(mExpandDuration); 4012801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen alphaOa.setInterpolator(new AccelerateInterpolator(2.0f)); 4022801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen alphaOa.start(); 4032801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 404df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 4052801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.addListener(new AnimatorListenerAdapter() { 406df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 407df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 408df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 409df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 410df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 411df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 4122801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_OPEN; 4138dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen setLayerType(LAYER_TYPE_NONE, null); 4148dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen enableHardwareLayersForChildren(); 415df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 416df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 4172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.setDuration(mExpandDuration); 4182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.start(); 419df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 420df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 4218dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen void enableHardwareLayersForChildren() { 4228dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen ArrayList<View> children = getItemsInReadingOrder(); 4238dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen for (View child: children) { 4248dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen child.setLayerType(LAYER_TYPE_HARDWARE, null); 4258dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 4268dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 4278dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 428df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void animateClosed() { 4298e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen if (!(getParent() instanceof DragLayer)) return; 4308dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen setLayerType(LAYER_TYPE_HARDWARE, null); 4318dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen buildLayer(); 432df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 4332801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen ObjectAnimator oa; 4342801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mMode == PARTIAL_GROW) { 4352801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0); 4362801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 0.9f); 4372801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 0.9f); 4382801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa = ObjectAnimator.ofPropertyValuesHolder(this, alpha, scaleX, scaleY); 4392801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 4408e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 4412801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 4423e8f811f31a2275e778244427271f77f4116c08bAdam Cohen PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", mIconRect.width()); 4433e8f811f31a2275e778244427271f77f4116c08bAdam Cohen PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", mIconRect.height()); 4443e8f811f31a2275e778244427271f77f4116c08bAdam Cohen PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", mIconRect.left); 4453e8f811f31a2275e778244427271f77f4116c08bAdam Cohen PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", mIconRect.top); 4462801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y); 4472801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.addUpdateListener(new AnimatorUpdateListener() { 4482801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen public void onAnimationUpdate(ValueAnimator animation) { 4492801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen requestLayout(); 4502801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 4512801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen }); 4522801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 4532801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0f); 4542801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen ObjectAnimator alphaOa = ObjectAnimator.ofPropertyValuesHolder(mContent, alpha); 4552801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen alphaOa.setDuration(mExpandDuration); 4562801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen alphaOa.setInterpolator(new DecelerateInterpolator(2.0f)); 4572801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen alphaOa.start(); 4582801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 459df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 4602801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.addListener(new AnimatorListenerAdapter() { 461df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 462df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationEnd(Animator animation) { 46376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen onClose(); 4642801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen onCloseComplete(); 4652801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mState = STATE_SMALL; 466df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 467df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen @Override 468df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public void onAnimationStart(Animator animation) { 469df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mState = STATE_ANIMATING; 470df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 471df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen }); 4722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.setDuration(mExpandDuration); 4732801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen oa.start(); 474df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 475df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 476df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen void notifyDataSetChanged() { 477df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen // recreate all the children if the data set changes under us. We may want to do this more 478df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen // intelligently (ie just removing the views that should no longer exist) 479df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mContent.removeAllViewsInLayout(); 480df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen bind(mInfo); 481df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 482df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 483cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public boolean acceptDrop(DragObject d) { 484cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen final ItemInfo item = (ItemInfo) d.dragInfo; 485df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen final int itemType = item.itemType; 4862801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || 4872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) && 4882801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen !isFull()); 489df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 490df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 491df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen protected boolean findAndSetEmptyCells(ShortcutInfo item) { 492df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen int[] emptyCell = new int[2]; 493df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen if (mContent.findCellForSpan(emptyCell, item.spanX, item.spanY)) { 494df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen item.cellX = emptyCell[0]; 495df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen item.cellY = emptyCell[1]; 496df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return true; 497df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } else { 498df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return false; 499df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 500df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 501df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 502c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen protected boolean createAndAddShortcut(ShortcutInfo item) { 503df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen final TextView textView = 504e87b924efaaf1cfb555a4327dc653929a4c182f1Adam Cohen (TextView) mInflater.inflate(R.layout.application, this, false); 505df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen textView.setCompoundDrawablesWithIntrinsicBounds(null, 506df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen new FastBitmapDrawable(item.getIcon(mIconCache)), null, null); 507df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen textView.setText(item.title); 508df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen textView.setTag(item); 509df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 510df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen textView.setOnClickListener(this); 511df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen textView.setOnLongClickListener(this); 512df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 513c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // We need to check here to verify that the given item's location isn't already occupied 514c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // by another item. If it is, we need to find the next available slot and assign 515c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // it that position. This is an issue when upgrading from the old Folders implementation 516c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen // which could contain an unlimited number of items. 517c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen if (mContent.getChildAt(item.cellX, item.cellY) != null) { 518c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen if (!findAndSetEmptyCells(item)) { 519c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen return false; 520c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen } 521c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen } 522c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen 523df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen CellLayout.LayoutParams lp = 524df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen new CellLayout.LayoutParams(item.cellX, item.cellY, item.spanX, item.spanY); 525df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen boolean insert = false; 526df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen mContent.addViewToCellLayout(textView, insert ? 0 : -1, (int)item.id, lp, true); 527c508b2d701ef980875f7ebc71bf2d87781159478Adam Cohen return true; 528df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 529df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 530cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public void onDragEnter(DragObject d) { 531bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mPreviousTargetCell[0] = -1; 532bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mPreviousTargetCell[1] = -1; 533bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.cancelAlarm(); 534df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 535df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 536bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mReorderAlarmListener = new OnAlarmListener() { 537bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 538bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen realTimeReorder(mEmptyCell, mTargetCell); 539bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 540bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 541bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 542bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen boolean readingOrderGreaterThan(int[] v1, int[] v2) { 543bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (v1[1] > v2[1] || (v1[1] == v2[1] && v1[0] > v2[0])) { 544bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen return true; 545bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } else { 546bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen return false; 547bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 548df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 549df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 550bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private void realTimeReorder(int[] empty, int[] target) { 551bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen boolean wrap; 552bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen int startX; 553bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen int endX; 554bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen int startY; 55576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen int delay = 0; 55676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen float delayAmount = 30; 557bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (readingOrderGreaterThan(target, empty)) { 558bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen wrap = empty[0] >= mContent.getCountX() - 1; 559bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen startY = wrap ? empty[1] + 1 : empty[1]; 560bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen for (int y = startY; y <= target[1]; y++) { 561bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen startX = y == empty[1] ? empty[0] + 1 : 0; 562bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen endX = y < target[1] ? mContent.getCountX() - 1 : target[0]; 563bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen for (int x = startX; x <= endX; x++) { 564bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen View v = mContent.getChildAt(x,y); 565bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (mContent.animateChildToPosition(v, empty[0], empty[1], 56676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen REORDER_ANIMATION_DURATION, delay)) { 567bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen empty[0] = x; 568bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen empty[1] = y; 56976fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen delay += delayAmount; 57076fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen delayAmount *= 0.9; 571bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 572bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 573bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 574bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } else { 575bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen wrap = empty[0] == 0; 576bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen startY = wrap ? empty[1] - 1 : empty[1]; 577bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen for (int y = startY; y >= target[1]; y--) { 578bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen startX = y == empty[1] ? empty[0] - 1 : mContent.getCountX() - 1; 579bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen endX = y > target[1] ? 0 : target[0]; 580bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen for (int x = startX; x >= endX; x--) { 581bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen View v = mContent.getChildAt(x,y); 582bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (mContent.animateChildToPosition(v, empty[0], empty[1], 58376fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen REORDER_ANIMATION_DURATION, delay)) { 584bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen empty[0] = x; 585bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen empty[1] = y; 58676fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen delay += delayAmount; 58776fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen delayAmount *= 0.9; 588bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 589bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 590bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 591bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 592bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 593bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 594bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragOver(DragObject d) { 595bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen float[] r = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, d.dragView, null); 596bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mTargetCell = mContent.findNearestArea((int) r[0], (int) r[1], 1, 1, mTargetCell); 597bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 598bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (mTargetCell[0] != mPreviousTargetCell[0] || mTargetCell[1] != mPreviousTargetCell[1]) { 599bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mReorderAlarm.cancelAlarm(); 600bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mReorderAlarm.setOnAlarmListener(mReorderAlarmListener); 601bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mReorderAlarm.setAlarm(150); 602bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mPreviousTargetCell[0] = mTargetCell[0]; 603bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mPreviousTargetCell[1] = mTargetCell[1]; 604bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 605df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 606df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 607bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // This is used to compute the visual center of the dragView. The idea is that 608bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // the visual center represents the user's interpretation of where the item is, and hence 609bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // is the appropriate point to use when determining drop location. 610bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen private float[] getDragViewVisualCenter(int x, int y, int xOffset, int yOffset, 611bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen DragView dragView, float[] recycle) { 612bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen float res[]; 613bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (recycle == null) { 614bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen res = new float[2]; 615bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } else { 616bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen res = recycle; 617df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 6182801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 619bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // These represent the visual top and left of drag view if a dragRect was provided. 620bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // If a dragRect was not provided, then they correspond to the actual view left and 621bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // top, as the dragRect is in that case taken to be the entire dragView. 622bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // R.dimen.dragViewOffsetY. 623bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen int left = x - xOffset; 624bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen int top = y - yOffset; 625bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 626bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // In order to find the visual center, we shift by half the dragRect 627bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen res[0] = left + dragView.getDragRegion().width() / 2; 628bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen res[1] = top + dragView.getDragRegion().height() / 2; 629bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 630bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen return res; 631bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 632bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 633bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen OnAlarmListener mOnExitAlarmListener = new OnAlarmListener() { 634bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAlarm(Alarm alarm) { 6353e8f811f31a2275e778244427271f77f4116c08bAdam Cohen completeDragExit(); 636bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 637bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen }; 6382801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 63995bb800de9b0142bea0110b074eddbcf0e475736Adam Cohen public void completeDragExit() { 6403e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mLauncher.closeFolder(); 6413e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragInfo = null; 6423e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mCurrentDragView = null; 6433e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mSuppressOnAdd = false; 6443e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mRearrangeOnClose = true; 6453e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 6463e8f811f31a2275e778244427271f77f4116c08bAdam Cohen 647bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDragExit(DragObject d) { 648bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // We only close the folder if this is a true drag exit, ie. not because a drop 649bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // has occurred above the folder. 650bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (!d.dragComplete) { 651bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setOnAlarmListener(mOnExitAlarmListener); 652bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mOnExitAlarm.setAlarm(ON_EXIT_CLOSE_DELAY); 653bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 654bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mReorderAlarm.cancelAlarm(); 6552801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 6562801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 657c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen public void onDropCompleted(View target, DragObject d, boolean success) { 658bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragInfo = null; 659bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mCurrentDragView = null; 660bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mSuppressOnAdd = false; 66176078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen if (!success) { 66276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen if (d.dragView != null) { 66376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen if (target instanceof CellLayout) { 66476078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen // TODO: we should animate the item back to the folder in this case 66576078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 66676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 667bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // TODO: if the drag fails, we need to re-add the item 6683e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } else { 6693e8f811f31a2275e778244427271f77f4116c08bAdam Cohen if (target != this) { 6703e8f811f31a2275e778244427271f77f4116c08bAdam Cohen mOnExitAlarm.cancelAlarm(); 6713e8f811f31a2275e778244427271f77f4116c08bAdam Cohen completeDragExit(); 6723e8f811f31a2275e778244427271f77f4116c08bAdam Cohen } 67376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 674df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 675df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 676df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen public boolean isDropEnabled() { 677df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return true; 678df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen } 679df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen 680cb3382b1bfe1a534b1b44f5c4def9b2db605ac90Adam Cohen public DropTarget getDropTargetDelegate(DragObject d) { 681df2cc41acbfacd576f99483a4af1cda32ebd3d09Adam Cohen return null; 68231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 683a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 6842801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void setupContentDimension(int count) { 6852801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen ArrayList<View> list = getItemsInReadingOrder(); 6862801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 6872801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int countX = mContent.getCountX(); 6882801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int countY = mContent.getCountY(); 6897c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen boolean done = false; 6907c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen 6917c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen while (!done) { 6927c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen int oldCountX = countX; 6937c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen int oldCountY = countY; 6947c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (countX * countY < count) { 6957c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen // Current grid is too small, expand it 6967c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (countX <= countY && countX < mMaxCountX) { 6977c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen countX++; 6987c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } else if (countY < mMaxCountY) { 6997c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen countY++; 7007c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 7017c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (countY == 0) countY++; 7027c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } else if ((countY - 1) * countX >= count && countY >= countX) { 7037c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen countY = Math.max(0, countY - 1); 7047c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } else if ((countX - 1) * countY >= count) { 7057c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen countX = Math.max(0, countX - 1); 7062801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7077c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen done = countX == oldCountX && countY == oldCountY; 7082801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7097c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mContent.setGridSize(countX, countY); 7102801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen arrangeChildren(list); 7112801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7122801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7132801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen public boolean isFull() { 7142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return getItemCount() >= mMaxCountX * mMaxCountY; 7152801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void centerAboutIcon() { 7188e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 7192801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 721f4bb1cdecd3cf866a1d87b7b8560234fa7dd4cc5Adam Cohen int height = getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight() 722f4bb1cdecd3cf866a1d87b7b8560234fa7dd4cc5Adam Cohen + mFolderNameHeight; 7238e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer); 7248e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen 7258e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen parent.getDescendantRectRelativeToSelf(mFolderIcon, mTempRect); 7262801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7278e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen int centerX = mTempRect.centerX(); 7288e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen int centerY = mTempRect.centerY(); 7292801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredLeft = centerX - width / 2; 7302801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int centeredTop = centerY - height / 2; 7312801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 73235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We first fetch the currently visible CellLayoutChildren 7333d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung CellLayout currentPage = mLauncher.getWorkspace().getCurrentDropLayout(); 73435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen CellLayoutChildren boundingLayout = currentPage.getChildrenLayout(); 73535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen Rect bounds = new Rect(); 73635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen parent.getDescendantRectRelativeToSelf(boundingLayout, bounds); 73735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen 73835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // We need to bound the folder to the currently visible CellLayoutChildren 73935e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int left = Math.min(Math.max(bounds.left, centeredLeft), 74035e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.left + bounds.width() - width); 74135e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen int top = Math.min(Math.max(bounds.top, centeredTop), 74235e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen bounds.top + bounds.height() - height); 74335e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen // If the folder doesn't fit within the bounds, center it about the desired bounds 74435e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen if (width >= bounds.width()) { 74535e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen left = bounds.left + (bounds.width() - width) / 2; 74635e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen } 74735e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen if (height >= bounds.height()) { 74835e7e64d4b98e42c760e5e91489b7014a6ba9073Adam Cohen top = bounds.top + (bounds.height() - height) / 2; 7490e4857c302da6adbd45231d7a8bae0289fa33250Adam Cohen } 7502801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7512801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotX = width / 2 + (centeredLeft - left); 7522801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderPivotY = height / 2 + (centeredTop - top); 7532801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotX(folderPivotX); 7542801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setPivotY(folderPivotY); 7552801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * 7562801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotX / width)); 7572801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int folderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * 7582801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen (1.0f * folderPivotY / height)); 7592801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mFolderIcon.setPivotX(folderIconPivotX); 7602801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mFolderIcon.setPivotY(folderIconPivotY); 7612801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7622801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mMode == PARTIAL_GROW) { 7632801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen lp.width = width; 7642801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen lp.height = height; 7652801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen lp.x = left; 7662801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen lp.y = top; 7672801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 7682801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mNewSize.set(left, top, left + width, top + height); 7692801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7702801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7712801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void setupContentForNumItems(int count) { 7732801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setupContentDimension(count); 7742801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 7758e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams(); 7762801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (lp == null) { 7778e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen lp = new DragLayer.LayoutParams(0, 0); 7788e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen lp.customPosition = true; 7792801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setLayoutParams(lp); 7802801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7812801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen centerAboutIcon(); 7822801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 7832801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 784234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 785234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth(); 786f4bb1cdecd3cf866a1d87b7b8560234fa7dd4cc5Adam Cohen int height = getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight() 787f4bb1cdecd3cf866a1d87b7b8560234fa7dd4cc5Adam Cohen + mFolderNameHeight; 788234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen 789234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen int contentWidthSpec = MeasureSpec.makeMeasureSpec(mContent.getDesiredWidth(), 790234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen MeasureSpec.EXACTLY); 791234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen int contentHeightSpec = MeasureSpec.makeMeasureSpec(mContent.getDesiredHeight(), 792234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen MeasureSpec.EXACTLY); 793234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen mContent.measure(contentWidthSpec, contentHeightSpec); 794234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen 795234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen mFolderName.measure(contentWidthSpec, 796234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen MeasureSpec.makeMeasureSpec(mFolderNameHeight, MeasureSpec.EXACTLY)); 797234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen setMeasuredDimension(width, height); 798234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen } 799234c4cd54406e363a2ebc213f6ae5be284414988Adam Cohen 8002801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void arrangeChildren(ArrayList<View> list) { 8012801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen int[] vacant = new int[2]; 8022801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (list == null) { 8032801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen list = getItemsInReadingOrder(); 8042801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 8052801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mContent.removeAllViews(); 8062801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 8072801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen for (int i = 0; i < list.size(); i++) { 8082801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen View v = list.get(i); 8092801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mContent.getVacantCell(vacant, 1, 1); 8102801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) v.getLayoutParams(); 8112801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen lp.cellX = vacant[0]; 8122801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen lp.cellY = vacant[1]; 8132801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen ItemInfo info = (ItemInfo) v.getTag(); 8142801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen info.cellX = vacant[0]; 8152801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen info.cellY = vacant[1]; 8162801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen boolean insert = false; 8172801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mContent.addViewToCellLayout(v, insert ? 0 : -1, (int)info.id, lp, true); 8187c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen LauncherModel.addOrMoveItemInDatabase(mLauncher, info, mInfo.id, 0, 8197c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen info.cellX, info.cellY); 8202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 8217c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 8222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 8232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 824a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public int getItemCount() { 825a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen return mContent.getChildrenLayout().getChildCount(); 826a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 827a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 828a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public View getItemAt(int index) { 829a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen return mContent.getChildrenLayout().getChildAt(index); 830a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 831a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen 8322801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen private void onCloseComplete() { 8332801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mRearrangeOnClose) { 8342801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setupContentForNumItems(getItemCount()); 8352801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = false; 8362801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 837afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 838afb01ee74243cede19088e694ca82cea5983c603Adam Cohen replaceFolderWithFinalItem(); 839afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 840afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 841afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 842afb01ee74243cede19088e694ca82cea5983c603Adam Cohen private void replaceFolderWithFinalItem() { 843afb01ee74243cede19088e694ca82cea5983c603Adam Cohen ItemInfo finalItem = null; 844afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 845afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() == 1) { 846afb01ee74243cede19088e694ca82cea5983c603Adam Cohen finalItem = mInfo.contents.get(0); 847afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 848afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 849afb01ee74243cede19088e694ca82cea5983c603Adam Cohen // Remove the folder completely 8503d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung CellLayout cellLayout = mLauncher.getCellLayout(mInfo.container, mInfo.screen); 851afb01ee74243cede19088e694ca82cea5983c603Adam Cohen cellLayout.removeView(mFolderIcon); 852afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (mFolderIcon instanceof DropTarget) { 853afb01ee74243cede19088e694ca82cea5983c603Adam Cohen mDragController.removeDropTarget((DropTarget) mFolderIcon); 854afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 855afb01ee74243cede19088e694ca82cea5983c603Adam Cohen mLauncher.removeFolder(mInfo); 856afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 857afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (finalItem != null) { 8583d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container, 8593d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung mInfo.screen, mInfo.cellX, mInfo.cellY); 860afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 861716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen LauncherModel.deleteItemFromDatabase(mLauncher, mInfo); 862afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 863afb01ee74243cede19088e694ca82cea5983c603Adam Cohen // Add the last remaining child to the workspace in place of the folder 864afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (finalItem != null) { 865afb01ee74243cede19088e694ca82cea5983c603Adam Cohen View child = mLauncher.createShortcut(R.layout.application, cellLayout, 866afb01ee74243cede19088e694ca82cea5983c603Adam Cohen (ShortcutInfo) finalItem); 867afb01ee74243cede19088e694ca82cea5983c603Adam Cohen 8683d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung mLauncher.getWorkspace().addInScreen(child, mInfo.container, mInfo.screen, mInfo.cellX, 8693d503fbd9468fb2b9fa645f4f7b91e11229edbfaWinson Chung mInfo.cellY, mInfo.spanX, mInfo.spanY); 870afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 8712801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 8722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 873bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onDrop(DragObject d) { 874bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen ShortcutInfo item; 875bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (d.dragInfo instanceof ApplicationInfo) { 876bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // Came from all apps -- make a copy 877bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen item = ((ApplicationInfo) d.dragInfo).makeShortcut(); 878bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen item.spanX = 1; 879bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen item.spanY = 1; 880bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } else { 881bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen item = (ShortcutInfo) d.dragInfo; 882bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 883bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // Dragged from self onto self 884bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (item == mCurrentDragInfo) { 885bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen ShortcutInfo si = (ShortcutInfo) mCurrentDragView.getTag(); 886bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mCurrentDragView.getLayoutParams(); 887bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen si.cellX = lp.cellX = mEmptyCell[0]; 888bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen si.cellX = lp.cellY = mEmptyCell[1]; 889bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mContent.addViewToCellLayout(mCurrentDragView, -1, (int)item.id, lp, true); 890fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen if (d.dragView.hasDrawn()) { 891fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, mCurrentDragView); 892fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen } else { 893fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen mCurrentDragView.setVisibility(VISIBLE); 894fc53cd22c9a78708c78c85946443f23ec8c59502Adam Cohen } 895e9166b247addcf67542ababb9d453f5bfb33c7b2Adam Cohen mItemsInvalidated = true; 896bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen setupContentDimension(getItemCount()); 897716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen mSuppressOnAdd = true; 898bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 899bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mInfo.add(item); 900bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 901bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 902bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen public void onAdd(ShortcutInfo item) { 903bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mItemsInvalidated = true; 904bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (mSuppressOnAdd) return; 905bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (!findAndSetEmptyCells(item)) { 906bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen // The current layout is full, can we expand it? 907bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen setupContentForNumItems(getItemCount() + 1); 908bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen findAndSetEmptyCells(item); 909bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 910bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen createAndAddShortcut(item); 911bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen LauncherModel.addOrMoveItemInDatabase( 912bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen mLauncher, item, mInfo.id, 0, item.cellX, item.cellY); 913bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen } 914bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen 915a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen public void onRemove(ShortcutInfo item) { 9167c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = true; 917bfbfd26c627a18f8e1e3e6d0e53e78feab360203Adam Cohen if (item == mCurrentDragInfo) return; 918df1e4e868a1970b756486dadd652651d40276d36Adam Cohen View v = getViewForInfo(item); 919a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen mContent.removeView(v); 9202801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen if (mState == STATE_ANIMATING) { 9212801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen mRearrangeOnClose = true; 9222801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } else { 9232801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen setupContentForNumItems(getItemCount()); 9242801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 925afb01ee74243cede19088e694ca82cea5983c603Adam Cohen if (getItemCount() <= 1) { 926afb01ee74243cede19088e694ca82cea5983c603Adam Cohen replaceFolderWithFinalItem(); 927afb01ee74243cede19088e694ca82cea5983c603Adam Cohen } 928a9cf38f533d1e86269868f1e6a806ccffd4a78fcAdam Cohen } 9297c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen 930df1e4e868a1970b756486dadd652651d40276d36Adam Cohen private View getViewForInfo(ShortcutInfo item) { 931df1e4e868a1970b756486dadd652651d40276d36Adam Cohen for (int j = 0; j < mContent.getCountY(); j++) { 932df1e4e868a1970b756486dadd652651d40276d36Adam Cohen for (int i = 0; i < mContent.getCountX(); i++) { 933df1e4e868a1970b756486dadd652651d40276d36Adam Cohen View v = mContent.getChildAt(i, j); 934df1e4e868a1970b756486dadd652651d40276d36Adam Cohen if (v.getTag() == item) { 935df1e4e868a1970b756486dadd652651d40276d36Adam Cohen return v; 936df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 937df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 938df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 939df1e4e868a1970b756486dadd652651d40276d36Adam Cohen return null; 940df1e4e868a1970b756486dadd652651d40276d36Adam Cohen } 941df1e4e868a1970b756486dadd652651d40276d36Adam Cohen 94276078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen public void onItemsChanged() { 94376078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 94476fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen public void onTitleChanged(CharSequence title) { 94576fc085d28178a5d4fb3787ede956281a2cc3179Adam Cohen } 94676078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 9477c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen public ArrayList<View> getItemsInReadingOrder() { 94876078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen return getItemsInReadingOrder(true); 94976078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 95076078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen 95176078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen public ArrayList<View> getItemsInReadingOrder(boolean includeCurrentDragItem) { 9527c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (mItemsInvalidated) { 9537c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInReadingOrder.clear(); 9547c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen for (int j = 0; j < mContent.getCountY(); j++) { 9557c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen for (int i = 0; i < mContent.getCountX(); i++) { 9567c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen View v = mContent.getChildAt(i, j); 9577c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen if (v != null) { 95876078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen ShortcutInfo info = (ShortcutInfo) v.getTag(); 95976078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen if (info != mCurrentDragInfo || includeCurrentDragItem) { 96076078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen mItemsInReadingOrder.add(v); 96176078c4ef35b6e95fb6d8129a32cf52a36625e28Adam Cohen } 9627c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 9637c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 9647c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 9657c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen mItemsInvalidated = false; 9667c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 9677c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen return mItemsInReadingOrder; 9687c6932140dcbd2db88d7a809ba72ee04abb5bf26Adam Cohen } 9698dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen 9708dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen public void getLocationInDragLayer(int[] loc) { 9718dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen mLauncher.getDragLayer().getLocationInDragLayer(this, loc); 9728dfcba4af7a7ece09e8c7d96053e54f3a383e905Adam Cohen } 97331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 974