Workspace.java revision 678862186af4ea70d9b4012c9bc127e7fea5e607
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 190280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.app.WallpaperManager; 208edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurkaimport android.content.Context; 21b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.content.Intent; 220280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.content.ComponentName; 23cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroyimport android.content.res.TypedArray; 24cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroyimport android.content.pm.PackageManager; 25716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohenimport android.graphics.Canvas; 26cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroyimport android.graphics.RectF; 2768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport android.graphics.Rect; 288f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornimport android.graphics.drawable.Drawable; 29629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.util.AttributeSet; 30629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.view.MotionEvent; 31a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.view.VelocityTracker; 32a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.view.View; 33495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.view.ViewConfiguration; 3431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.ViewGroup; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.ViewParent; 36495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.widget.Scroller; 377247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroyimport android.widget.TextView; 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.os.Parcelable; 394be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoimport android.os.Parcel; 406b879f0a5885274a85333531e091283405d490ccAdam Lesinski 4131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport java.util.ArrayList; 42a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 43a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung/** 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * The workspace is a wide area with a wallpaper and a finite number of screens. Each 45a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung * screen contains a number of icons, folders or widgets the user can interact with. 464be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * A workspace is meant to be used with a fixed width only. 47f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project */ 48956091ba7863bd72086275e61084864994dd6fa7Joe Onoratopublic class Workspace extends ViewGroup implements DropTarget, DragSource, DragScroller { 49495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell private static final int INVALID_SCREEN = -1; 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 51b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung /** 52291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler * The velocity at which a fling gesture will cause us to snap to the next screen 53580e27748137ff08599aa719d106b31215a28353Winson Chung */ 54a34abf8c781485b788fddacb352d586bffca886cWinson Chung private static final int SNAP_VELOCITY = 1000; 55a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private final WallpaperManager mWallpaperManager; 5731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 586e3140865d3f0def2e55934d8b0b2c1503386e54Winson Chung private int mDefaultScreen; 59cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 60f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project private boolean mFirstLayout = true; 61a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int mCurrentScreen; 636639687cd67bab1aeef2a75e5c6bc458b20dc082Adam Cohen private int mNextScreen = INVALID_SCREEN; 6419072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen private Scroller mScroller; 656639687cd67bab1aeef2a75e5c6bc458b20dc082Adam Cohen private VelocityTracker mVelocityTracker; 66edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 67716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen /** 68716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen * CellInfo for the cell that is currently being dragged 69716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen */ 70716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen private CellLayout.CellInfo mDragInfo; 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 720142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka /** 730142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * Target drop area calculated during last acceptDrop call. 74aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung */ 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int[] mTargetCell = null; 760142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 77e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy private float mLastMotionX; 78e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy private float mLastMotionY; 79e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy 803a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato private final static int TOUCH_STATE_REST = 0; 810142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private final static int TOUCH_STATE_SCROLLING = 1; 82f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 83f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private int mTouchState = TOUCH_STATE_REST; 84a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 85a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private OnLongClickListener mLongClickListener; 86a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 871b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen private Launcher mLauncher; 88a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private DragController mDragController; 891b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen 90a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen /** 9168d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen * Cache of vacant cells, used during drag events and invalidated as needed. 9268d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen */ 939171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung private CellLayout.CellInfo mVacantCache = null; 94f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 95f135c6c364e92cddb84c1b4a94ed535214b712a6Winson Chung private int[] mTempCell = new int[2]; 969171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung private int[] mTempEstimate = new int[2]; 979171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 989171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung private boolean mAllowLongPress = true; 999171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 1009171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung private int mTouchSlop; 1019171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung private int mMaximumVelocity; 1029171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 1039171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung final Rect mDrawerBounds = new Rect(); 104e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka final Rect mClipBounds = new Rect(); 105e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka int mDrawerContentHeight; 1069171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung int mDrawerContentWidth; 10725356e75ebae5d6e0be43f38d2c73b5cb59d05f2Michael Jurka 108f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen /** 10968d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen * Used to inflate the Workspace from XML. 110e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen * 111f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen * @param context The application's context. 112f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung * @param attrs The attribtues set containing the Workspace's customization values. 11388127038178b3bbf0eb91103a31e682cc0615074Winson Chung */ 1148f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn public Workspace(Context context, AttributeSet attrs) { 1159c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka this(context, attrs, 0); 116aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 1170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 11831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 119d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka * Used to inflate the Workspace from XML. 120e0310965022e7a1adb7ad489505d404186608689Adam Cohen * 12121f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen * @param context The application's context. 12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param attrs The attribtues set containing the Workspace's customization values. 12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param defStyle Unused. 12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 12531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Workspace(Context context, AttributeSet attrs, int defStyle) { 126aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung super(context, attrs, defStyle); 12770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 12870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey mWallpaperManager = WallpaperManager.getInstance(context); 12970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 130c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Workspace, defStyle, 0); 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDefaultScreen = a.getInt(R.styleable.Workspace_defaultScreen, 1); 1326569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy a.recycle(); 1336569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1346569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy initWorkspace(); 1356569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 1366569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 1380589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * Initializes various states for this workspace. 13900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato */ 140aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung private void initWorkspace() { 1414516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mScroller = new Scroller(getContext()); 1424516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mCurrentScreen = mDefaultScreen; 14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Launcher.setScreen(mCurrentScreen); 14470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 145e3e27a854f3eca363d3c5ce353d19de475272d87Adam Cohen final ViewConfiguration configuration = ViewConfiguration.get(getContext()); 146a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka mTouchSlop = configuration.getScaledTouchSlop(); 1474516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); 1484516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 149a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 150c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen @Override 1510280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka public void addView(View child, int index, LayoutParams params) { 152073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen if (!(child instanceof CellLayout)) { 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 154c2f7f4794867cd1b3e97fd0f379ad8ad15958a6cMichael Jurka } 155b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung super.addView(child, index, params); 156d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka } 157d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen 158d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen @Override 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child) { 1601262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy if (!(child instanceof CellLayout)) { 161dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 162c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka } 163c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka super.addView(child); 164bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurka } 165b8e14479da7209ca811a753b3256fe4a0b49a873Michael Jurka 166f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung @Override 167af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka public void addView(View child, int index) { 168883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka if (!(child instanceof CellLayout)) { 169af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 1703c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka } 171dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka super.addView(child, index); 17254fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy } 1731262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1741262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy @Override 17554fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy public void addView(View child, int width, int height) { 17654fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy if (!(child instanceof CellLayout)) { 17754fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 1788e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy } 1794be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato super.addView(child, width, height); 1808e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy } 1818e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy 1824be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato @Override 183a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung public void addView(View child, LayoutParams params) { 184a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung if (!(child instanceof CellLayout)) { 185a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 1866b879f0a5885274a85333531e091283405d490ccAdam Lesinski } 1876b879f0a5885274a85333531e091283405d490ccAdam Lesinski super.addView(child, params); 1886b879f0a5885274a85333531e091283405d490ccAdam Lesinski } 1896b879f0a5885274a85333531e091283405d490ccAdam Lesinski 1906b879f0a5885274a85333531e091283405d490ccAdam Lesinski /** 191c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * @return The open folder on the current screen, or null if there is none 192c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka */ 193c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka Folder getOpenFolder() { 194ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka CellLayout currentScreen = (CellLayout) getChildAt(mCurrentScreen); 195c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka int count = currentScreen.getChildCount(); 196ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka for (int i = 0; i < count; i++) { 19726976d9b53161f80faf822d482ac771b8621cf31Adam Cohen View child = currentScreen.getChildAt(i); 198c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 1990bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) { 2000bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka return (Folder) child; 2010bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka } 2020bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka } 2030bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka return null; 2040bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka } 2050bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka 20619072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen ArrayList<Folder> getOpenFolders() { 207c0dcf597084d00e4c23a7fea5fd0738f6c095a6bAdam Cohen final int screens = getChildCount(); 20819072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen ArrayList<Folder> folders = new ArrayList<Folder>(screens); 20919072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen 21019072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen for (int screen = 0; screen < screens; screen++) { 21119072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen CellLayout currentScreen = (CellLayout) getChildAt(screen); 21219072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen int count = currentScreen.getChildCount(); 21319072da7441e07d5e90026d9e9e1b38f11245e44Adam Cohen for (int i = 0; i < count; i++) { 214073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen View child = currentScreen.getChildAt(i); 215f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 216f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) { 217f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen folders.add((Folder) child); 218f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen break; 219f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen } 220f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen } 221f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen } 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return folders; 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2260142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka boolean isDefaultScreenShowing() { 22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return mCurrentScreen == mDefaultScreen; 22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns the index of the currently displayed screen. 23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return The index of the currently displayed screen. 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int getCurrentScreen() { 2360142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return mCurrentScreen; 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 24031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns how many screens there are. 2410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka */ 2425f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int getScreenCount() { 243f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung return getChildCount(); 244f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 245f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 246a2eb17095dcffa75c1e9681fdc318fe6e0564321Michael Jurka /** 2475f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * Computes a bounding rectangle for a range of cells 2485f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka * 24931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param cellX X coordinate of upper left corner expressed as a cell position 2508f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn * @param cellY Y coordinate of upper left corner expressed as a cell position 251aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * @param cellHSpan Width in cells 252f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka * @param cellVSpan Height in cells 253f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka * @param rect Rectnagle into which to put the results 254f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka */ 255aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void cellToRect(int cellX, int cellY, int cellHSpan, int cellVSpan, RectF rect) { 256aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung ((CellLayout)getChildAt(mCurrentScreen)).cellToRect(cellX, cellY, 257f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka cellHSpan, cellVSpan, rect); 258b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung } 259f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka 260f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka /** 261f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka * Sets the current screen. 262f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka * 263f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka * @param currentScreen 264b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung */ 265b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung void setCurrentScreen(int currentScreen) { 266b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung clearVacantCache(); 267f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1)); 268f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka scrollTo(mCurrentScreen * getWidth(), 0); 269f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka updateWallpaperOffset(); 270f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka invalidate(); 271f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka } 272f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka 273f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka /** 274f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka * Shows the default screen (defined by the firstScreen attribute in XML.) 275f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka */ 276f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka void showDefaultScreen() { 277f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka setCurrentScreen(mDefaultScreen); 278f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka } 279f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka 280f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka /** 281f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka * Adds the specified child in the current screen. The position and dimension of 282f61249b79948a4b37b38104cbe81c98086d1f30bMichael Jurka * the child are defined by x, y, spanX and spanY. 283f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka * 284f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka * @param child The child to add in one of the workspace's screens. 285f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka * @param x The X position of the child in the screen's grid. 286b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung * @param y The Y position of the child in the screen's grid. 287b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung * @param spanX The number of cells spanned horizontally by the child. 288b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung * @param spanY The number of cells spanned vertically by the child. 289f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka */ 290f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka void addInCurrentScreen(View child, int x, int y, int spanX, int spanY) { 291f6440da9d02f3ee1553db4bd431a202eb1d1a9ddMichael Jurka addInScreen(child, mCurrentScreen, x, y, spanX, spanY, false); 2920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 295d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen * Adds the specified child in the current screen. The position and dimension of 2960d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato * the child are defined by x, y, spanX and spanY. 2970142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * 29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 299c35afb2c9df8cc56c77bf21ce2eaa213f6f31251Winson Chung * @param x The X position of the child in the screen's grid. 300c35afb2c9df8cc56c77bf21ce2eaa213f6f31251Winson Chung * @param y The Y position of the child in the screen's grid. 301c35afb2c9df8cc56c77bf21ce2eaa213f6f31251Winson Chung * @param spanX The number of cells spanned horizontally by the child. 30231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 30331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param insert When true, the child is inserted at the beginning of the children list. 30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInCurrentScreen(View child, int x, int y, int spanX, int spanY, boolean insert) { 30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project addInScreen(child, mCurrentScreen, x, y, spanX, spanY, insert); 3070142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 3080589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato 3090142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka /** 3100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * Adds the specified child in the specified screen. The position and dimension of 3110589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * the child are defined by x, y, spanX and spanY. 3120589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato * 313a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung * @param child The child to add in one of the workspace's screens. 314cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy * @param screen The screen in which to add the child. 31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 316b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung * @param y The Y position of the child in the screen's grid. 317b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung * @param spanX The number of cells spanned horizontally by the child. 318fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung * @param spanY The number of cells spanned vertically by the child. 319b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung */ 320b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung void addInScreen(View child, int screen, int x, int y, int spanX, int spanY) { 321b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung addInScreen(child, screen, x, y, spanX, spanY, false); 3229171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung } 3238edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka 3243c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka /** 325c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka * Adds the specified child in the specified screen. The position and dimension of 326c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka * the child are defined by x, y, spanX and spanY. 327c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka * 3280bb8563b1381d92b0d7dbb5b0f814ad656c2f9bdMichael Jurka * @param child The child to add in one of the workspace's screens. 3293c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka * @param screen The screen in which to add the child. 3308edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka * @param x The X position of the child in the screen's grid. 331c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka * @param y The Y position of the child in the screen's grid. 332ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka * @param spanX The number of cells spanned horizontally by the child. 333f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung * @param spanY The number of cells spanned vertically by the child. 334f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung * @param insert When true, the child is inserted at the beginning of the children list. 335f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung */ 336f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung void addInScreen(View child, int screen, int x, int y, int spanX, int spanY, boolean insert) { 337f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung if (screen < 0 || screen >= getChildCount()) { 338f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung throw new IllegalStateException("The screen must be >= 0 and < " + getChildCount()); 339a58f8bb1947af39d4d18d849b3e4d6bd0d3954d7Winson Chung } 340ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka 34160b7c53ccc6384b65aaca77d97794e8f09e8cfc8Patrick Dubroy clearVacantCache(); 342ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka 343bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurka final CellLayout group = (CellLayout) getChildAt(screen); 344bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurka CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 345bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurka if (lp == null) { 346bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurka lp = new CellLayout.LayoutParams(x, y, spanX, spanY); 347ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka } else { 348ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka lp.cellX = x; 349ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka lp.cellY = y; 350ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka lp.cellHSpan = spanX; 351bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurka lp.cellVSpan = spanY; 352ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 35360b7c53ccc6384b65aaca77d97794e8f09e8cfc8Patrick Dubroy group.addView(child, insert ? 0 : -1, lp); 354dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka if (!(child instanceof Folder)) { 355dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka child.setOnLongClickListener(mLongClickListener); 3560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 357ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (child instanceof DropTarget) { 35831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragController.addDropTarget((DropTarget)child); 35931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 36031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 361f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 362b26f3d6a8c62e7c1a603b6c7979375d8dd4f20d4Winson Chung void addWidget(View view, Widget widget) { 363f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen addInScreen(view, widget.screen, widget.cellX, widget.cellY, widget.spanX, 364f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen widget.spanY, false); 365e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka } 36631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 36731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addWidget(View view, Widget widget, boolean insert) { 36831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project addInScreen(view, widget.screen, widget.cellX, widget.cellY, widget.spanX, 3692801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen widget.spanY, insert); 3702801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen } 3712801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen 3722801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen CellLayout.CellInfo findAllVacantCells(boolean[] occupied) { 3732801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen CellLayout group = (CellLayout) getChildAt(mCurrentScreen); 374e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka if (group != null) { 3752801cafe62653131fdc9da402e5c44e5ffd0bf47Adam Cohen return group.findAllVacantCells(occupied, null); 376e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka } 377e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka return null; 378e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka } 37931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 38031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void clearVacantCache() { 38131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mVacantCache != null) { 38231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mVacantCache.clearVacantCells(); 38331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mVacantCache = null; 384e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka } 38531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 38631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 38731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 38831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Returns the coordinate of a vacant cell for the current screen. 38931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 390e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka boolean getVacantCell(int[] vacant, int spanX, int spanY) { 39131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout group = (CellLayout) getChildAt(mCurrentScreen); 39231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (group != null) { 39331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return group.getVacantCell(vacant, spanX, spanY); 39431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 39531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 396e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka } 39731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 39831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 39931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the current screen. The position and dimension of 40031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 40131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 402e5fb0f27bca7afb996258a7163c76ca7390d7bffMichael Jurka * @param child The child to add in one of the workspace's screens. 40331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 40431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 40531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 40631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void fitInCurrentScreen(View child, int spanX, int spanY) { 40731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project fitInScreen(child, mCurrentScreen, spanX, spanY); 40831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 40931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 410716b51e030f9c6ed34af2b947760e46a280c65a6Adam Cohen /** 4118e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen * Adds the specified child in the specified screen. The position and dimension of 41231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 4138e776a62c5cc60737f5cdbbeacfec5f958112fa7Adam Cohen * 414aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * @param child The child to add in one of the workspace's screens. 415aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * @param screen The screen in which to add the child. 416aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * @param spanX The number of cells spanned horizontally by the child. 417aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * @param spanY The number of cells spanned vertically by the child. 41831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 41931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void fitInScreen(View child, int screen, int spanX, int spanY) { 42031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (screen < 0 || screen >= getChildCount()) { 42131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalStateException("The screen must be >= 0 and < " + getChildCount()); 42231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 423a0aa0121b91fde17e427ab2763ce312e64cf5d33Patrick Dubroy 424a0aa0121b91fde17e427ab2763ce312e64cf5d33Patrick Dubroy final CellLayout group = (CellLayout) getChildAt(screen); 42531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean vacant = group.getVacantCell(mTempCell, spanX, spanY); 42631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (vacant) { 42731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project group.addView(child, 42831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project new CellLayout.LayoutParams(mTempCell[0], mTempCell[1], spanX, spanY)); 42931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project child.setOnLongClickListener(mLongClickListener); 43031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof Folder)) { 43131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project child.setOnLongClickListener(mLongClickListener); 43231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (child instanceof DropTarget) { 43431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragController.addDropTarget((DropTarget)child); 43531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 43931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 44031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Registers the specified listener on each screen contained in this workspace. 44131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 442aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * @param l The listener used to respond to long clicks. 443aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung */ 444aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung @Override 445aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void setOnLongClickListener(OnLongClickListener l) { 44631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLongClickListener = l; 44731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int count = getChildCount(); 44831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 44931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project getChildAt(i).setOnLongClickListener(l); 45031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 45131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 45231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 45331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void updateWallpaperOffset() { 45431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateWallpaperOffset(getChildAt(getChildCount() - 1).getRight() - (mRight - mLeft)); 45531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 45631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 45731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private void updateWallpaperOffset(int scrollRange) { 45831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mWallpaperManager.setWallpaperOffsets(getWindowToken(), mScrollX / (float) scrollRange, 0); 45931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 460291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler 461291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler @Override 462291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler public void computeScroll() { 46331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mScroller.computeScrollOffset()) { 46431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollX = mScroller.getCurrX(); 46531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mScrollY = mScroller.getCurrY(); 46631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project updateWallpaperOffset(); 46731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project postInvalidate(); 46831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (mNextScreen != INVALID_SCREEN) { 46931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1)); 47031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Launcher.setScreen(mCurrentScreen); 47131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mNextScreen = INVALID_SCREEN; 47231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project clearChildrenCache(); 47331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 47431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 475aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 4767f4eabe3709a72b416569136e4a095431c493c8bAdam Cohen @Override 4777f4eabe3709a72b416569136e4a095431c493c8bAdam Cohen protected void dispatchDraw(Canvas canvas) { 4787f4eabe3709a72b416569136e4a095431c493c8bAdam Cohen boolean restore = false; 4797f4eabe3709a72b416569136e4a095431c493c8bAdam Cohen int restoreCount = 0; 4806569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 481845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka // For the fade. If view gets setAlpha(), use that instead. 482f3ca3ab6958b104cbf2c2fa04add97d372a94d1cMichael Jurka float scale = mScale; 483f3ca3ab6958b104cbf2c2fa04add97d372a94d1cMichael Jurka if (scale < 0.999f) { 484aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int sx = mScrollX; 485aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 4866569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy int alpha = (scale < 0.5f) ? (int)(255 * 2 * scale) : 255; 487aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 488aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung restoreCount = canvas.saveLayerAlpha(sx, 0, sx+getWidth(), getHeight(), alpha, 489aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); 49031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project restore = true; 4910d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato 49231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (scale < 0.999f) { 49331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int w = getWidth(); 49400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato w += 2 * mCurrentScreen * w; 495aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int dx = w/2; 49600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int h = getHeight(); 49731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int dy = (h/2) - (h/4); 49831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project canvas.translate(dx, dy); 499d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy canvas.scale(scale, scale); 500d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy canvas.translate(-dx, -dy); 501d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy } 502d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy } 503d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy 504d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy // ViewGroup.dispatchDraw() supports many features we don't need: 505d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy // clip to padding, layout animation, animation listener, disappearing 506d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy // children, etc. The following implementation attempts to fast-track 507d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy // the drawing dispatch by drawing only what we know needs to be drawn. 508d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy 509d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy boolean fastDraw = mTouchState != TOUCH_STATE_SCROLLING && mNextScreen == INVALID_SCREEN 510d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy && scale > 0.999f; 511d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy // If we are not scrolling or flinging, draw only the current screen 512d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy if (fastDraw) { 513d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy drawChild(canvas, getChildAt(mCurrentScreen), getDrawingTime()); 514d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy } else { 515d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy final long drawingTime = getDrawingTime(); 516d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy // If we are flinging, draw only the current screen and the target screen 517d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy if (mNextScreen >= 0 && mNextScreen < getChildCount() && 518d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy Math.abs(mCurrentScreen - mNextScreen) == 1) { 519d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy drawChild(canvas, getChildAt(mCurrentScreen), drawingTime); 520d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy drawChild(canvas, getChildAt(mNextScreen), drawingTime); 521d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy } else { 522d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy // If we are scrolling, draw all of our children 523d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy final int count = getChildCount(); 524d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy for (int i = 0; i < count; i++) { 525d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy drawChild(canvas, getChildAt(i), drawingTime); 526d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy } 527d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy } 528d0ce1ec2e21ce3bb0ba3549a01d1d06b440a8e45Patrick Dubroy } 529e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy 530e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy if (restore) { 531e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy canvas.restoreToCount(restoreCount); 532e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy } 533e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy } 534e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy 535dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka private float mScale = 1.0f; 536e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy public void setScale(float scale) { 537e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy mScale = scale; 538e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy invalidate(); 539e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy } 540e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy 541e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy protected void onAttachedToWindow() { 542e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy super.onAttachedToWindow(); 543e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy mDragController.setWindowToken(getWindowToken()); 544e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy } 545e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy 546e708c5249b26978057acb9370cbfb8f6f747f5b8Patrick Dubroy @Override 547dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 5480e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka super.onMeasure(widthMeasureSpec, heightMeasureSpec); 5490e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka 550ded9f8d8658d0b6601006c0a954cd3bf530e55c1Adam Cohen final int width = MeasureSpec.getSize(widthMeasureSpec); 551ded9f8d8658d0b6601006c0a954cd3bf530e55c1Adam Cohen final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 552ded9f8d8658d0b6601006c0a954cd3bf530e55c1Adam Cohen if (widthMode != MeasureSpec.EXACTLY) { 553ded9f8d8658d0b6601006c0a954cd3bf530e55c1Adam Cohen throw new IllegalStateException("Workspace can only be used in EXACTLY mode."); 5545f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 5555f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 556c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 5575f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka if (heightMode != MeasureSpec.EXACTLY) { 5585f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka throw new IllegalStateException("Workspace can only be used in EXACTLY mode."); 5595f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 5605f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 5615f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka // The children are given the same width and height as the workspace 5625f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka final int count = getChildCount(); 5635f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka for (int i = 0; i < count; i++) { 5645f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec); 565f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen } 566f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen 567f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen if (mFirstLayout) { 568f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen scrollTo(mCurrentScreen * width, 0); 569f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen updateWallpaperOffset(width * (getChildCount() - 1)); 5705f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mFirstLayout = false; 5715f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 5725f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 5731adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka 5741adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka @Override 57569c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 57669c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen int childLeft = 0; 57769c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen 578f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen final int count = getChildCount(); 57969c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen for (int i = 0; i < count; i++) { 580f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen final View child = getChildAt(i); 58169c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen if (child.getVisibility() != View.GONE) { 58269c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen final int childWidth = child.getMeasuredWidth(); 583f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen child.layout(childLeft, 0, childLeft + childWidth, child.getMeasuredHeight()); 58469c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen childLeft += childWidth; 58569c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen } 58669c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen } 587f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen } 58869c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen 58969c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen @Override 59069c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) { 59169c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen int screen = indexOfChild(child); 59269c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen if (screen != mCurrentScreen || !mScroller.isFinished()) { 59369c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen if (!mLauncher.isWorkspaceLocked()) { 59469c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen snapToScreen(screen); 59569c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen } 59669c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen return true; 59769c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen } 59869c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen return false; 59969c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen } 60069c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen 60169c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen @Override 60269c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 60369c42da4d30f1cbba5fe1ac8960b4e305e14b807Adam Cohen if (!mLauncher.isAllAppsVisible()) { 604f8d2823d885ba682140aee1ae0504c1c5e67a24bAdam Cohen final Folder openFolder = getOpenFolder(); 6051adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka if (openFolder != null) { 6061adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka return openFolder.requestFocus(direction, previouslyFocusedRect); 607007c69867d821ea2b271398577a8b3440b3a7046Winson Chung } else { 608007c69867d821ea2b271398577a8b3440b3a7046Winson Chung int focusableScreen; 609007c69867d821ea2b271398577a8b3440b3a7046Winson Chung if (mNextScreen != INVALID_SCREEN) { 610007c69867d821ea2b271398577a8b3440b3a7046Winson Chung focusableScreen = mNextScreen; 611007c69867d821ea2b271398577a8b3440b3a7046Winson Chung } else { 6121262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy focusableScreen = mCurrentScreen; 613007c69867d821ea2b271398577a8b3440b3a7046Winson Chung } 614007c69867d821ea2b271398577a8b3440b3a7046Winson Chung getChildAt(focusableScreen).requestFocus(direction, previouslyFocusedRect); 6150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 6160142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 61716fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka return false; 6180142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 6190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 6200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 62116fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka public boolean dispatchUnhandledMove(View focused, int direction) { 62231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (direction == View.FOCUS_LEFT) { 623007c69867d821ea2b271398577a8b3440b3a7046Winson Chung if (getCurrentScreen() > 0) { 624007c69867d821ea2b271398577a8b3440b3a7046Winson Chung snapToScreen(getCurrentScreen() - 1); 625007c69867d821ea2b271398577a8b3440b3a7046Winson Chung return true; 626007c69867d821ea2b271398577a8b3440b3a7046Winson Chung } 627007c69867d821ea2b271398577a8b3440b3a7046Winson Chung } else if (direction == View.FOCUS_RIGHT) { 62831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (getCurrentScreen() < getChildCount() - 1) { 62931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project snapToScreen(getCurrentScreen() + 1); 6301262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy return true; 631007c69867d821ea2b271398577a8b3440b3a7046Winson Chung } 632007c69867d821ea2b271398577a8b3440b3a7046Winson Chung } 63316fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka return super.dispatchUnhandledMove(focused, direction); 6341262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 6351262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 636007c69867d821ea2b271398577a8b3440b3a7046Winson Chung @Override 637007c69867d821ea2b271398577a8b3440b3a7046Winson Chung public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { 638007c69867d821ea2b271398577a8b3440b3a7046Winson Chung if (!mLauncher.isAllAppsVisible()) { 639007c69867d821ea2b271398577a8b3440b3a7046Winson Chung final Folder openFolder = getOpenFolder(); 6401262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy if (openFolder == null) { 64168d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen getChildAt(mCurrentScreen).addFocusables(views, direction); 642e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen if (direction == View.FOCUS_LEFT) { 64326976d9b53161f80faf822d482ac771b8621cf31Adam Cohen if (mCurrentScreen > 0) { 64426976d9b53161f80faf822d482ac771b8621cf31Adam Cohen getChildAt(mCurrentScreen - 1).addFocusables(views, direction); 64526976d9b53161f80faf822d482ac771b8621cf31Adam Cohen } 64626976d9b53161f80faf822d482ac771b8621cf31Adam Cohen } else if (direction == View.FOCUS_RIGHT){ 64726976d9b53161f80faf822d482ac771b8621cf31Adam Cohen if (mCurrentScreen < getChildCount() - 1) { 6480142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka getChildAt(mCurrentScreen + 1).addFocusables(views, direction); 6490142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 6500142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 6510142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 6520142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka openFolder.addFocusables(views, direction); 6530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 6540142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 6550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 656c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 657c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka @Override 658c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka public boolean onInterceptTouchEvent(MotionEvent ev) { 659c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka if (mLauncher.isWorkspaceLocked() || mLauncher.isAllAppsVisible()) { 660c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka return false; // We don't want the events. Let them fall through to the all apps view. 661c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka } 662c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 663c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka /* 664c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * This method JUST determines whether we want to intercept the motion. 665c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * If we return true, onTouchEvent will be called and we do the actual 666c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * scrolling there. 667c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka */ 668c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 669c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka /* 670c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * Shortcut the most recurring case: the user is in the dragging 671c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * state and he is moving his finger. We want to intercept this 672c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * motion. 673c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka */ 674c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka final int action = ev.getAction(); 675c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) { 676c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka return true; 677c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka } 678c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 679c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka final float x = ev.getX(); 680c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka final float y = ev.getY(); 681c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 682c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka switch (action) { 683c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka case MotionEvent.ACTION_MOVE: 684c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka /* 685c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * mIsBeingDragged == false, otherwise the shortcut would have caught it. Check 686c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * whether the user has moved far enough from his original down touch. 687c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka */ 688c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 689c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka /* 690c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * Locally do absolute value. mLastMotionX is set to the y value 691c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka * of the down event. 692c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka */ 693c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka final int xDiff = (int) Math.abs(x - mLastMotionX); 694c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka final int yDiff = (int) Math.abs(y - mLastMotionY); 695c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 696201bc828d5a0078f505e8e37152156a0cb43c10aWinson Chung final int touchSlop = mTouchSlop; 697201bc828d5a0078f505e8e37152156a0cb43c10aWinson Chung boolean xMoved = xDiff > touchSlop; 698201bc828d5a0078f505e8e37152156a0cb43c10aWinson Chung boolean yMoved = yDiff > touchSlop; 699201bc828d5a0078f505e8e37152156a0cb43c10aWinson Chung 700c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka if (xMoved || yMoved) { 701c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 702c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka if (xMoved) { 703c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka // Scroll if the user moved far enough along the X axis 704c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka mTouchState = TOUCH_STATE_SCROLLING; 705f7640c8bba304ba99c99afcd7393893eccc9a0d9Winson Chung enableChildrenCache(); 706f7640c8bba304ba99c99afcd7393893eccc9a0d9Winson Chung } 707f7640c8bba304ba99c99afcd7393893eccc9a0d9Winson Chung // Either way, cancel any pending longpress 708f7640c8bba304ba99c99afcd7393893eccc9a0d9Winson Chung if (mAllowLongPress) { 709f7640c8bba304ba99c99afcd7393893eccc9a0d9Winson Chung mAllowLongPress = false; 710c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka // Try canceling the long press. It could also have been scheduled 711c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka // by a distant descendant, so use the mAllowLongPress flag to block 712ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka // everything 713ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final View currentScreen = getChildAt(mCurrentScreen); 714ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka currentScreen.cancelLongPress(); 715ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 716ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 717ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka break; 718ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 719ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka case MotionEvent.ACTION_DOWN: 720ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka // Remember location of down touch 721ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mLastMotionX = x; 722ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mLastMotionY = y; 723c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka mAllowLongPress = true; 724c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 725ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka /* 726ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka * If being flinged and user touches the screen, initiate drag; 727f70c78142457b0e9c691f2a20ed87407c7433f5bMichael Jurka * otherwise don't. mScroller.isFinished should be false when 728ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka * being flinged. 729ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka */ 730ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING; 731ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka break; 732ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 733f70c78142457b0e9c691f2a20ed87407c7433f5bMichael Jurka case MotionEvent.ACTION_CANCEL: 734f70c78142457b0e9c691f2a20ed87407c7433f5bMichael Jurka case MotionEvent.ACTION_UP: 735f70c78142457b0e9c691f2a20ed87407c7433f5bMichael Jurka // Release the drag 736ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka clearChildrenCache(); 737ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mTouchState = TOUCH_STATE_REST; 738ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mAllowLongPress = false; 739ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka break; 740ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 741ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 74209d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka /* 74309d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka * The only time we want to intercept motion events is if we are in the 74409d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka * drag mode. 74509d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka */ 74609d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka return mTouchState != TOUCH_STATE_REST; 74709d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka } 74809d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka 74909d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka void enableChildrenCache() { 75009d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka final int count = getChildCount(); 75109d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka for (int i = 0; i < count; i++) { 75209d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka final CellLayout layout = (CellLayout) getChildAt(i); 75309d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka layout.setChildrenDrawnWithCacheEnabled(true); 75409d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka layout.setChildrenDrawingCacheEnabled(true); 755ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 75609d6eb0f3fb1d81ea59881e6c65512d09d573cc1Michael Jurka } 757ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 758f70c78142457b0e9c691f2a20ed87407c7433f5bMichael Jurka void clearChildrenCache() { 759ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final int count = getChildCount(); 760ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka for (int i = 0; i < count; i++) { 761ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final CellLayout layout = (CellLayout) getChildAt(i); 762ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka layout.setChildrenDrawnWithCacheEnabled(false); 763b46a2d130b3d04df830402d579060b63db559ae3Winson Chung } 764b46a2d130b3d04df830402d579060b63db559ae3Winson Chung } 765ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 766c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka @Override 767c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka public boolean onTouchEvent(MotionEvent ev) { 768c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 769c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka if (mLauncher.isWorkspaceLocked() || mLauncher.isAllAppsVisible()) { 770c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka return false; // We don't want the events. Let them fall through to the all apps view. 771c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka } 772c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 773ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (mVelocityTracker == null) { 774ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mVelocityTracker = VelocityTracker.obtain(); 775ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 776ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mVelocityTracker.addMovement(ev); 777ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 778ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final int action = ev.getAction(); 779ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final float x = ev.getX(); 780ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 781c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka switch (action) { 782ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka case MotionEvent.ACTION_DOWN: 783ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka /* 784ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka * If being flinged and user touches, stop the fling. isFinished 7859c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka * will be false if being flinged. 7869c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka */ 787ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (!mScroller.isFinished()) { 788ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mScroller.abortAnimation(); 789ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 790ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 7912763be3150d429d338b9848286e9365b4052c100Michael Jurka // Remember where the motion event started 792956091ba7863bd72086275e61084864994dd6fa7Joe Onorato mLastMotionX = x; 793ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka break; 794ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka case MotionEvent.ACTION_MOVE: 795ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (mTouchState == TOUCH_STATE_SCROLLING) { 796ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka // Scroll to follow the motion event 797ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final int deltaX = (int) (mLastMotionX - x); 798ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mLastMotionX = x; 799ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 800ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (deltaX < 0) { 801ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka if (mScrollX > 0) { 802ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka scrollBy(Math.max(-mScrollX, deltaX), 0); 803ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka updateWallpaperOffset(); 804ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 805ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } else if (deltaX > 0) { 806ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final int availableToScroll = getChildAt(getChildCount() - 1).getRight() - 807ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mScrollX - getWidth(); 808ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (availableToScroll > 0) { 809ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka scrollBy(Math.min(availableToScroll, deltaX), 0); 810ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka updateWallpaperOffset(); 811ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 812ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 813ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 814ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka break; 815ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka case MotionEvent.ACTION_UP: 816ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka if (mTouchState == TOUCH_STATE_SCROLLING) { 817ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka final VelocityTracker velocityTracker = mVelocityTracker; 818ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); 819ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka int velocityX = (int) velocityTracker.getXVelocity(); 820ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka 821ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) { 822ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka // Fling hard enough to move left 823ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka snapToScreen(mCurrentScreen - 1); 824ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } else if (velocityX < -SNAP_VELOCITY && mCurrentScreen < getChildCount() - 1) { 825ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka // Fling hard enough to move right 826ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka snapToScreen(mCurrentScreen + 1); 827ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } else { 828ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka snapToDestination(); 829ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 830ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 831ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (mVelocityTracker != null) { 832ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mVelocityTracker.recycle(); 833ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mVelocityTracker = null; 834ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 835ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 836ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka mTouchState = TOUCH_STATE_REST; 837ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka break; 838ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka case MotionEvent.ACTION_CANCEL: 839ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka mTouchState = TOUCH_STATE_REST; 840ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 841ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka 842ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka return true; 843ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 844ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka 845ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka private void snapToDestination() { 846ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka final int screenWidth = getWidth(); 847ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka final int whichScreen = (mScrollX + (screenWidth / 2)) / screenWidth; 848ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka 849ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka snapToScreen(whichScreen); 850ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 851ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka 852ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka void snapToScreen(int whichScreen) { 853ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (!mScroller.isFinished()) return; 854ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 855ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka clearVacantCache(); 856ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka enableChildrenCache(); 857ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka 858ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); 859ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka boolean changingScreens = whichScreen != mCurrentScreen; 860ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 861ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mNextScreen = whichScreen; 862ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 863ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka View focusedChild = getFocusedChild(); 864ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka if (focusedChild != null && changingScreens && focusedChild == getChildAt(mCurrentScreen)) { 865ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka focusedChild.clearFocus(); 866ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka } 867ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 868ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final int newX = whichScreen * getWidth(); 869ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final int delta = newX - mScrollX; 870ca5b836e16d320f17057cd1a40a93c382e72501aMichael Jurka mScroller.startScroll(mScrollX, 0, delta, 0, Math.abs(delta) * 2); 871ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka invalidate(); 872ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 873ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 874ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka void startDrag(CellLayout.CellInfo cellInfo) { 875ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka View child = cellInfo.cell; 876ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 877ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka // Make sure the drag was started by a long press as opposed to a long click. 878ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka // Note that Search takes focus when clicked rather than entering touch mode 879ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka if (!child.isInTouchMode() && !(child instanceof Search)) { 880ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka return; 881ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 882ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 883ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mDragInfo = cellInfo; 884ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mDragInfo.screen = mCurrentScreen; 885ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 886ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka CellLayout current = ((CellLayout) getChildAt(mCurrentScreen)); 887ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 888ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka current.onDragChild(child); 889ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka mDragController.startDrag(child, this, child.getTag(), DragController.DRAG_ACTION_MOVE); 890ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka invalidate(); 891ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 892ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 893ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka @Override 894ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka protected Parcelable onSaveInstanceState() { 895ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka final SavedState state = new SavedState(super.onSaveInstanceState()); 896ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka state.currentScreen = mCurrentScreen; 897ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka return state; 898ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 899ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 900ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka @Override 901ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka protected void onRestoreInstanceState(Parcelable state) { 902ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka SavedState savedState = (SavedState) state; 9038f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn super.onRestoreInstanceState(savedState.getSuperState()); 904aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (savedState.currentScreen != -1) { 905340c5f3a708efa280a120708594247952ca65182Michael Jurka mCurrentScreen = savedState.currentScreen; 906340c5f3a708efa280a120708594247952ca65182Michael Jurka Launcher.setScreen(mCurrentScreen); 907340c5f3a708efa280a120708594247952ca65182Michael Jurka } 908ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka } 909ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka 910ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka void addApplicationShortcut(ApplicationInfo info, CellLayout.CellInfo cellInfo) { 911340c5f3a708efa280a120708594247952ca65182Michael Jurka addApplicationShortcut(info, cellInfo, false); 912340c5f3a708efa280a120708594247952ca65182Michael Jurka } 91394f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy 9143e7c7634531302271270c8cf418abc959d621cbcMichael Jurka void addApplicationShortcut(ApplicationInfo info, CellLayout.CellInfo cellInfo, 9159171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung boolean insertAtFirst) { 9169171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung final CellLayout layout = (CellLayout) getChildAt(cellInfo.screen); 9179171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung final int[] result = new int[2]; 9189171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 9199171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung layout.cellToPoint(cellInfo.cellX, cellInfo.cellY, result); 9203e7c7634531302271270c8cf418abc959d621cbcMichael Jurka onDropExternal(result[0], result[1], info, layout, insertAtFirst); 921f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 922f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 92394f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, 9243e7c7634531302271270c8cf418abc959d621cbcMichael Jurka DragView dragView, Object dragInfo) { 9259171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung final CellLayout cellLayout = getCurrentDropLayout(); 9269171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung if (source != this) { 9279171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung onDropExternal(x - xOffset, y - yOffset, dragInfo, cellLayout); 9289171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung } else { 9299171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung // Move internally 9309171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung if (mDragInfo != null) { 9313e7c7634531302271270c8cf418abc959d621cbcMichael Jurka final View cell = mDragInfo.cell; 932f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen int index = mScroller.isFinished() ? mCurrentScreen : mNextScreen; 933f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (index != mDragInfo.screen) { 93494f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen); 93594f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy originalCellLayout.removeView(cell); 93694f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy cellLayout.addView(cell); 93794f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy } 93894f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy mTargetCell = estimateDropCell(x - xOffset, y - yOffset, 93994f78a5c44c08b258f59b2c78ff6694e5eaca827Patrick Dubroy mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout, mTargetCell); 9409171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung cellLayout.onDropChild(cell, mTargetCell); 9419171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 942f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen final ItemInfo info = (ItemInfo)cell.getTag(); 943f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams(); 944f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen LauncherModel.moveItemInDatabase(mLauncher, info, 945f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen LauncherSettings.Favorites.CONTAINER_DESKTOP, index, lp.cellX, lp.cellY); 946f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 947f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 9489171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung } 9499171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 9509171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, 9519171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung DragView dragView, Object dragInfo) { 9529c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka clearVacantCache(); 9539c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka } 9549c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka 9559c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, 9569c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka DragView dragView, Object dragInfo) { 9579c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka } 9589c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka 959760e5375f003accf04f789e90a919ed476d4c335Winson Chung public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, 960760e5375f003accf04f789e90a919ed476d4c335Winson Chung DragView dragView, Object dragInfo) { 9618d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chung clearVacantCache(); 9628d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chung } 9638d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chung 964b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout) { 9659171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung onDropExternal(x, y, dragInfo, cellLayout, false); 9669171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung } 967e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka 968e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka private void onDropExternal(int x, int y, Object dragInfo, CellLayout cellLayout, 969e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka boolean insertAtFirst) { 970e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka // Drag from somewhere else 971e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka ItemInfo info = (ItemInfo) dragInfo; 972e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka 973f135c6c364e92cddb84c1b4a94ed535214b712a6Winson Chung View view; 9749171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 9759171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung switch (info.itemType) { 9769171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 9779171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 9788d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chung if (info.container == NO_ID) { 979b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung // Came from all apps -- make a copy 9809171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung info = new ApplicationInfo((ApplicationInfo) info); 9819171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung } 982e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka view = mLauncher.createShortcut(R.layout.application, cellLayout, 983e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka (ApplicationInfo) info); 984e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka break; 985e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 986e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, 987e0f5a61a1f105216b0067124bacac69194c0ef70Michael Jurka (ViewGroup) getChildAt(mCurrentScreen), ((UserFolderInfo) info)); 988f135c6c364e92cddb84c1b4a94ed535214b712a6Winson Chung break; 9899171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung default: 9909171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung throw new IllegalStateException("Unknown item type: " + info.itemType); 9919171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung } 9929171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 9939171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung cellLayout.addView(view, insertAtFirst ? 0 : -1); 9949c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka view.setOnLongClickListener(mLongClickListener); 9959c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka if (view instanceof DropTarget) { 9969c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka mDragController.addDropTarget((DropTarget)view); 9979c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka } 9989171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 9999171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout, mTargetCell); 1000f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cellLayout.onDropChild(view, mTargetCell); 1001f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); 1002f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 1003f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen LauncherModel.addOrMoveItemInDatabase(mLauncher, info, 10046b879f0a5885274a85333531e091283405d490ccAdam Lesinski LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentScreen, lp.cellX, lp.cellY); 10056b879f0a5885274a85333531e091283405d490ccAdam Lesinski } 10066b879f0a5885274a85333531e091283405d490ccAdam Lesinski 10076b879f0a5885274a85333531e091283405d490ccAdam Lesinski /** 10086b879f0a5885274a85333531e091283405d490ccAdam Lesinski * Return the current {@link CellLayout}, correctly picking the destination 10096b879f0a5885274a85333531e091283405d490ccAdam Lesinski * screen while a scroll is in progress. 10106b879f0a5885274a85333531e091283405d490ccAdam Lesinski */ 10116b879f0a5885274a85333531e091283405d490ccAdam Lesinski private CellLayout getCurrentDropLayout() { 10126b879f0a5885274a85333531e091283405d490ccAdam Lesinski int index = mScroller.isFinished() ? mCurrentScreen : mNextScreen; 10136b879f0a5885274a85333531e091283405d490ccAdam Lesinski return (CellLayout) getChildAt(index); 10146b879f0a5885274a85333531e091283405d490ccAdam Lesinski } 10156b879f0a5885274a85333531e091283405d490ccAdam Lesinski 10166b879f0a5885274a85333531e091283405d490ccAdam Lesinski /** 10176b879f0a5885274a85333531e091283405d490ccAdam Lesinski * {@inheritDoc} 10186b879f0a5885274a85333531e091283405d490ccAdam Lesinski */ 10196b879f0a5885274a85333531e091283405d490ccAdam Lesinski public boolean acceptDrop(DragSource source, int x, int y, 10206b879f0a5885274a85333531e091283405d490ccAdam Lesinski int xOffset, int yOffset, DragView dragView, Object dragInfo) { 10216b879f0a5885274a85333531e091283405d490ccAdam Lesinski final CellLayout layout = getCurrentDropLayout(); 10226b879f0a5885274a85333531e091283405d490ccAdam Lesinski final CellLayout.CellInfo cellInfo = mDragInfo; 10236b879f0a5885274a85333531e091283405d490ccAdam Lesinski final int spanX = cellInfo == null ? 1 : cellInfo.spanX; 10246b879f0a5885274a85333531e091283405d490ccAdam Lesinski final int spanY = cellInfo == null ? 1 : cellInfo.spanY; 10256b879f0a5885274a85333531e091283405d490ccAdam Lesinski 10266b879f0a5885274a85333531e091283405d490ccAdam Lesinski if (mVacantCache == null) { 10276b879f0a5885274a85333531e091283405d490ccAdam Lesinski final View ignoreView = cellInfo == null ? null : cellInfo.cell; 10286b879f0a5885274a85333531e091283405d490ccAdam Lesinski mVacantCache = layout.findAllVacantCells(null, ignoreView); 102968d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen } 103068d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 103168d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen return mVacantCache.findCellForSpan(mTempEstimate, spanX, spanY, false); 103268d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen } 103368d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 103468d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen /** 103568d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen * {@inheritDoc} 103668d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen */ 103768d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen public Rect estimateDropLocation(DragSource source, int x, int y, 103868d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen int xOffset, int yOffset, DragView dragView, Object dragInfo, Rect recycle) { 103968d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen final CellLayout layout = getCurrentDropLayout(); 104068d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 104168d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen final CellLayout.CellInfo cellInfo = mDragInfo; 1042e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen final int spanX = cellInfo == null ? 1 : cellInfo.spanX; 104368d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen final int spanY = cellInfo == null ? 1 : cellInfo.spanY; 104468d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen final View ignoreView = cellInfo == null ? null : cellInfo.cell; 104568d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 104668d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen final Rect location = recycle != null ? recycle : new Rect(); 104768d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 104868d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen // Find drop cell and convert into rectangle 104968d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen int[] dropCell = estimateDropCell(x - xOffset, y - yOffset, 105068d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen spanX, spanY, ignoreView, layout, mTempCell); 105168d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 105268d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen if (dropCell == null) { 1053f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen return null; 1054f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 1055007c69867d821ea2b271398577a8b3440b3a7046Winson Chung 1056007c69867d821ea2b271398577a8b3440b3a7046Winson Chung layout.cellToPoint(dropCell[0], dropCell[1], mTempEstimate); 1057c3bc26031cc5b36328bd7cdbcf04ff269dea11a5Adam Cohen location.left = mTempEstimate[0]; 1058785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung location.top = mTempEstimate[1]; 1059785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung 1060a2eb17095dcffa75c1e9681fdc318fe6e0564321Michael Jurka layout.cellToPoint(dropCell[0] + spanX, dropCell[1] + spanY, mTempEstimate); 1061c3bc26031cc5b36328bd7cdbcf04ff269dea11a5Adam Cohen location.right = mTempEstimate[0]; 106221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen location.bottom = mTempEstimate[1]; 106368d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 106421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen return location; 10651b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen } 10661b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen 1067d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka /** 106821f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen * Calculate the nearest cell where the given object would be dropped. 106921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen */ 1070f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private int[] estimateDropCell(int pixelX, int pixelY, 1071ddb821981e0919bbd3b4c9a2b6aa1811d6c86bb6Adam Cohen int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) { 107221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen // Create vacant cell cache if none exists 107321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen if (mVacantCache == null) { 1074f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen mVacantCache = layout.findAllVacantCells(null, ignoreView); 1075e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen } 1076e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen 1077e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen // Find the best target drop location 1078e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen return layout.findNearestVacantArea(pixelX, pixelY, 1079e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen spanX, spanY, mVacantCache, recycle); 1080e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen } 1081e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen 1082e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen void setLauncher(Launcher launcher) { 1083e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen mLauncher = launcher; 1084e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen } 1085e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen 10861b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen public void setDragController(DragController dragController) { 108721f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen mDragController = dragController; 10886b879f0a5885274a85333531e091283405d490ccAdam Lesinski } 10896b879f0a5885274a85333531e091283405d490ccAdam Lesinski 109068d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen public void onDropCompleted(View target, boolean success) { 10911b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen if (success){ 1092f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (target != this && mDragInfo != null) { 1093f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); 1094f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cellLayout.removeView(mDragInfo.cell); 1095f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (mDragInfo.cell instanceof DropTarget) { 109600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.removeDropTarget((DropTarget)mDragInfo.cell); 109700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 10989c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka final Object tag = mDragInfo.cell.getTag(); 1099956091ba7863bd72086275e61084864994dd6fa7Joe Onorato } 11009c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka } else { 11019c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka if (mDragInfo != null) { 11029c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); 11039c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka cellLayout.onDropAborted(mDragInfo.cell); 11049c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka } 110500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 110600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 110731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = null; 110828750fba6a2d141eb9a1e566718c17236030b815Michael Jurka } 1109c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 1110c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka public void scrollLeft() { 1111c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka clearVacantCache(); 11120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mNextScreen == INVALID_SCREEN && mCurrentScreen > 0 && mScroller.isFinished()) { 1113aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung snapToScreen(mCurrentScreen - 1); 111479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 111579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 1116883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka 1117696a67969d657d38eff33996633f08da0e21841fAdam Cohen public void scrollRight() { 1118696a67969d657d38eff33996633f08da0e21841fAdam Cohen clearVacantCache(); 1119696a67969d657d38eff33996633f08da0e21841fAdam Cohen if (mNextScreen == INVALID_SCREEN && mCurrentScreen < getChildCount() -1 && 1120696a67969d657d38eff33996633f08da0e21841fAdam Cohen mScroller.isFinished()) { 1121696a67969d657d38eff33996633f08da0e21841fAdam Cohen snapToScreen(mCurrentScreen + 1); 1122696a67969d657d38eff33996633f08da0e21841fAdam Cohen } 1123696a67969d657d38eff33996633f08da0e21841fAdam Cohen } 1124696a67969d657d38eff33996633f08da0e21841fAdam Cohen 112579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka public int getScreenForView(View v) { 112631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int result = -1; 112731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (v != null) { 112831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ViewParent vp = v.getParent(); 11299171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung int count = getChildCount(); 1130ab1983f46ce0ee0c94ea1170d21a67eb4e3c7967Michael Jurka for (int i = 0; i < count; i++) { 1131c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka if (vp == getChildAt(i)) { 11329171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung return i; 11339c6fbed48783dacd9bc6b4ec5f2cc8e59ec7ee37Michael Jurka } 11348d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chung } 1135f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 1136f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung return result; 1137f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung } 1138f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung 11399171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung /** 1140073a46ff635d089cbcb15d939d1de42dd2b86c97Adam Cohen * Find a search widget on the given screen 11419171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung */ 11429171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung private Search findSearchWidget(CellLayout screen) { 11439171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung final int count = screen.getChildCount(); 11449171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung for (int i = 0; i < count; i++) { 11450142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka View v = screen.getChildAt(i); 1146c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (v instanceof Search) { 11470142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return (Search) v; 11480142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 11490142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 11500142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return null; 1151a4b4016bcd90da673ba245f83621ef7128fa1cd6Michael Jurka } 1152a4b4016bcd90da673ba245f83621ef7128fa1cd6Michael Jurka 1153a4b4016bcd90da673ba245f83621ef7128fa1cd6Michael Jurka /** 11542763be3150d429d338b9848286e9365b4052c100Michael Jurka * Gets the first search widget on the current screen, if there is one. 11552763be3150d429d338b9848286e9365b4052c100Michael Jurka * Returns <code>null</code> otherwise. 11560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka */ 11570142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public Search findSearchWidgetOnCurrentScreen() { 11580142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout currentScreen = (CellLayout)getChildAt(mCurrentScreen); 1159cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy return findSearchWidget(currentScreen); 11600207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy } 11610207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy 11620207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy public Folder getFolderForTag(Object tag) { 11630207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy int screenCount = getChildCount(); 11640207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy for (int screen = 0; screen < screenCount; screen++) { 11650207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 11660207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy int count = currentScreen.getChildCount(); 11670207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy for (int i = 0; i < count; i++) { 11680207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy View child = currentScreen.getChildAt(i); 11690207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 11700207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) { 11710207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy Folder f = (Folder) child; 11720207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy if (f.getInfo() == tag) { 117333945b21544bc98381df17726a3537c292d8c985Michael Jurka return f; 1174967289b6d5fec77f5c381d11ffb2319f3bb5e737Winson Chung } 11750207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy } 11760207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy } 117733945b21544bc98381df17726a3537c292d8c985Michael Jurka } 1178967289b6d5fec77f5c381d11ffb2319f3bb5e737Winson Chung return null; 11790207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy } 11800207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy 11810207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy public View getViewForTag(Object tag) { 11820207c522472d7252f146f4d39efa456ca5248c6bPatrick Dubroy int screenCount = getChildCount(); 118331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int screen = 0; screen < screenCount; screen++) { 118431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 118531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int count = currentScreen.getChildCount(); 118631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 118731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = currentScreen.getChildAt(i); 1188678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato if (child.getTag() == tag) { 118931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return child; 119031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 119131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 119231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 11930142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return null; 119431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 119531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 119631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 119731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return True is long presses are still allowed for the current touch 119831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 119931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean allowLongPress() { 120097d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung return mAllowLongPress; 120197d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung } 120297d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung 120397d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung /** 120497d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung * Set true to allow long-press events to be triggered, usually checked by 120597d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung * {@link Launcher} to accept or block dpad-initiated long-presses. 120697d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung */ 120797d85d23b013347bead4e2f5fa430a79ce69431eWinson Chung public void setAllowLongPress(boolean allowLongPress) { 1208c2e24c0a37ddeab930f731c062705d435e477f75Romain Guy mAllowLongPress = allowLongPress; 1209678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato } 121031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 12110142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka void removeShortcutsForPackage(String packageName) { 121231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final ArrayList<View> childrenToRemove = new ArrayList<View>(); 12130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int count = getChildCount(); 12140142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 121531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 121631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 121731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int childCount = layout.getChildCount(); 121831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 12190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka childrenToRemove.clear(); 12200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 12210142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka for (int j = 0; j < childCount; j++) { 12220142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final View view = layout.getChildAt(j); 12230142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Object tag = view.getTag(); 12243a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron 1225aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (tag instanceof ApplicationInfo) { 1226dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final ApplicationInfo info = (ApplicationInfo) tag; 1227fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell // We need to check for ACTION_MAIN otherwise getComponent() might 12280142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // return null for some shortcuts (for instance, for shortcuts to 12290142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // web pages.) 1230fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell final Intent intent = info.intent; 12310142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final ComponentName name = intent.getComponent(); 123231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 123331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (Intent.ACTION_MAIN.equals(intent.getAction()) && 123431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project name != null && packageName.equals(name.getPackageName())) { 123531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project LauncherModel.deleteItemFromDatabase(mLauncher, info); 123631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project childrenToRemove.add(view); 123731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 123831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else if (tag instanceof UserFolderInfo) { 1239dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final UserFolderInfo info = (UserFolderInfo) tag; 1240dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final ArrayList<ApplicationInfo> contents = info.contents; 124131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final ArrayList<ApplicationInfo> toRemove = new ArrayList<ApplicationInfo>(1); 124231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int contentsCount = contents.size(); 124331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean removedFromFolder = false; 124431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 124531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int k = 0; k < contentsCount; k++) { 1246ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka final ApplicationInfo appInfo = contents.get(k); 1247ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka final Intent intent = appInfo.intent; 1248a7f801fc5b5715223e868ed599da69c5edf436eeMichael Jurka final ComponentName name = intent.getComponent(); 1249ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka 1250ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka if (Intent.ACTION_MAIN.equals(intent.getAction()) && 1251ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka name != null && packageName.equals(name.getPackageName())) { 1252ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka toRemove.add(appInfo); 1253ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka LauncherModel.deleteItemFromDatabase(mLauncher, appInfo); 1254ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka removedFromFolder = true; 1255ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka } 1256ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka } 1257ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka 1258ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka contents.removeAll(toRemove); 1259ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka if (removedFromFolder) { 1260ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka final Folder folder = getOpenFolder(); 1261ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka if (folder != null) folder.notifyDataSetChanged(); 1262ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka } 1263ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka } 1264ce7e05fbe8abd5f25ec47e0e05b5cc76ceb39d2eMichael Jurka } 12651d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown 12661d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown childCount = childrenToRemove.size(); 12671d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown for (int j = 0; j < childCount; j++) { 12681d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown View child = childrenToRemove.get(j); 12691d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown layout.removeViewInLayout(child); 12701d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown if (child instanceof DropTarget) { 12711d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown mDragController.removeDropTarget((DropTarget)child); 12721d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown } 12731d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown } 12741d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown 12751d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown if (childCount > 0) { 12761d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown layout.requestLayout(); 12771d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown layout.invalidate(); 12781d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown } 12791d0867c8de6a889bccde9b7e768daef182a25e5cJeff Brown } 128001f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka } 128101f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka 128201f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka void updateShortcutsForPackage(String packageName) { 128301f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka final PackageManager pm = mLauncher.getPackageManager(); 1284a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 1285a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen final int count = getChildCount(); 1286a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen for (int i = 0; i < count; i++) { 1287a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen final CellLayout layout = (CellLayout) getChildAt(i); 1288a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen int childCount = layout.getChildCount(); 1289a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen for (int j = 0; j < childCount; j++) { 1290a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen final View view = layout.getChildAt(j); 1291a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen Object tag = view.getTag(); 1292a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen if (tag instanceof ApplicationInfo) { 1293a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen ApplicationInfo info = (ApplicationInfo) tag; 1294a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // We need to check for ACTION_MAIN otherwise getComponent() might 1295a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // return null for some shortcuts (for instance, for shortcuts to 1296af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka // web pages.) 1297af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka final Intent intent = info.intent; 1298af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka final ComponentName name = intent.getComponent(); 12999171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && 13003c38d561e6976ffc54eda61ed669870bbb8ec207Michael Jurka Intent.ACTION_MAIN.equals(intent.getAction()) && name != null && 1301af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka packageName.equals(name.getPackageName())) { 1302af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka 1303883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka final Drawable icon = AppInfoCache.getIconDrawable(pm, info); 1304883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka if (icon != null && icon != info.icon) { 1305883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka info.icon.setCallback(null); 1306883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka info.icon = Utilities.createIconThumbnail(icon, mContext); 1307883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka info.filtered = true; 1308883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka ((TextView) view).setCompoundDrawablesWithIntrinsicBounds(null, 1309af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka info.icon, null, null); 1310883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka } 1311883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka } 13123e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 1313a997ac26664befbd0d5b172e36ef9e8b2c63b435Michael Jurka } 13143e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 13151b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen } 13160dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy 13170dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy void moveToDefaultScreen() { 13180dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy snapToScreen(mDefaultScreen); 13190dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy getChildAt(mDefaultScreen).requestFocus(); 13200dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy } 1321ddb821981e0919bbd3b4c9a2b6aa1811d6c86bb6Adam Cohen 1322ddb821981e0919bbd3b4c9a2b6aa1811d6c86bb6Adam Cohen public static class SavedState extends BaseSavedState { 1323ddb821981e0919bbd3b4c9a2b6aa1811d6c86bb6Adam Cohen int currentScreen = -1; 13241b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen 13251b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen SavedState(Parcelable superState) { 13260dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy super(superState); 13270dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy } 13280dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy 13290dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy private SavedState(Parcel in) { 13300dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy super(in); 13310dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy currentScreen = in.readInt(); 13320dfcf68b58bec1ac74f9b8700e3357f8e6d8b4a3Patrick Dubroy } 13337247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy 1334dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka @Override 1335213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka public void writeToParcel(Parcel out, int flags) { 13360142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.writeToParcel(out, flags); 1337244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy out.writeInt(currentScreen); 1338244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy } 1339244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy 13400142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public static final Parcelable.Creator<SavedState> CREATOR = 13410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka new Parcelable.Creator<SavedState>() { 13420142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public SavedState createFromParcel(Parcel in) { 13430142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return new SavedState(in); 1344244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy } 1345244d74cb353f1260c4d633e719bf84bb3b6e52bcPatrick Dubroy 1346a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen public SavedState[] newArray(int size) { 1347dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka return new SavedState[size]; 1348dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 1349a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen }; 1350213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 1351df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung 1352742574b15b2b5298a2328443176f2890fb8ebe98Michael Jurka void show() { 1353ef0066b52d2754ca0553ec79613c650b5649afaaWinson Chung setVisibility(VISIBLE); 1354ef0066b52d2754ca0553ec79613c650b5649afaaWinson Chung } 13553e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 13563e7c7634531302271270c8cf418abc959d621cbcMichael Jurka void hide() { 1357f16e571330f030e445c4f7f63f55d093337ffd87Adam Cohen } 1358af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka} 1359742574b15b2b5298a2328443176f2890fb8ebe98Michael Jurka