Workspace.java revision f3ca3ab6958b104cbf2c2fa04add97d372a94d1c
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 19af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport com.android.launcher.R; 20495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell 210280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.Animator; 22ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroyimport android.animation.Animator.AnimatorListener; 2318014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurkaimport android.animation.AnimatorListenerAdapter; 24b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.animation.AnimatorSet; 250280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.ObjectAnimator; 260280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.PropertyValuesHolder; 278f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornimport android.app.WallpaperManager; 28629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetManager; 29629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetProviderInfo; 30495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.content.ComponentName; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 3231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent; 33495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.content.pm.PackageManager; 345c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.content.pm.ProviderInfo; 357247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroyimport android.content.res.Resources; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.TypedArray; 374be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoimport android.graphics.Bitmap; 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas; 39a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurkaimport android.graphics.Matrix; 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Rect; 414be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoimport android.graphics.Region.Op; 42f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.graphics.drawable.Drawable; 435c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.net.Uri; 44956091ba7863bd72086275e61084864994dd6fa7Joe Onoratoimport android.os.IBinder; 45495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.os.Parcelable; 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 47291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandlerimport android.util.Log; 4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.MotionEvent; 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View; 50f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.widget.TextView; 5131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 52af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport java.util.ArrayList; 53af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport java.util.HashSet; 54edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 5531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * The workspace is a wide area with a wallpaper and a finite number of pages. 570142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * Each page contains a number of icons, folders or widgets the user can 58aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * interact with. A workspace is meant to be used with a fixed width only. 5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurkapublic class Workspace extends SmoothPagedView 61dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka implements DropTarget, DragSource, DragScroller, View.OnTouchListener { 62e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy @SuppressWarnings({"UnusedDeclaration"}) 633a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato private static final String TAG = "Launcher.Workspace"; 640142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 65dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // This is how much the workspace shrinks when we enter all apps or 66dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // customization mode 67dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka private static final float SHRINK_FACTOR = 0.16f; 68a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 69f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen // Y rotation to apply to the workspace screens 70f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final float WORKSPACE_ROTATION = 12.5f; 71a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 72a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // These are extra scale factors to apply to the mini home screens 73a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // so as to achieve the desired transform 74a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private static final float EXTRA_SCALE_FACTOR_0 = 0.97f; 75a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private static final float EXTRA_SCALE_FACTOR_1 = 1.0f; 76e54cec82a915c2bc8a7d719228c5d907f3fe14ecAdam Cohen private static final float EXTRA_SCALE_FACTOR_2 = 1.08f; 77a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 78f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final int BACKGROUND_FADE_OUT_DELAY = 300; 79f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final int BACKGROUND_FADE_OUT_DURATION = 300; 80f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final int BACKGROUND_FADE_IN_DURATION = 100; 81f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 823e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // These animators are used to fade the background 83472b281d5cb4f5660df981a6c912266b9f5703feChet Haase private ObjectAnimator mBackgroundFadeInAnimation; 84472b281d5cb4f5660df981a6c912266b9f5703feChet Haase private ObjectAnimator mBackgroundFadeOutAnimation; 85f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private float mBackgroundAlpha = 0; 86f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 878f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private final WallpaperManager mWallpaperManager; 88aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 890142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private int mDefaultPage; 9031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka private boolean mWaitingToShrinkToBottom = false; 9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 9321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen private boolean mPageMoving = false; 9421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen 9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 9631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * CellInfo for the cell that is currently being dragged 9731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 9831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private CellLayout.CellInfo mDragInfo; 99aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 10070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 10170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Target drop area calculated during last acceptDrop call. 10270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 10370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private int[] mTargetCell = null; 10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1056569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy /** 1066569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy * The CellLayout that is currently being dragged over 1076569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy */ 1086569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy private CellLayout mDragTargetLayout = null; 1096569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 11031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Launcher mLauncher; 1110589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private IconCache mIconCache; 11200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private DragController mDragController; 113aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1144516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // These are temporary variables to prevent having to allocate a new object just to 1154516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // return an (x, y) value from helper functions. Do NOT use them to maintain other state. 11631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int[] mTempCell = new int[2]; 11770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private int[] mTempEstimate = new int[2]; 1180280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka private float[] mTempOriginXY = new float[2]; 119a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka private float[] mTempDragCoordinates = new float[2]; 1204516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka private float[] mTempTouchCoordinates = new float[2]; 1214516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka private float[] mTempCellLayoutCenterCoordinates = new float[2]; 122a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka private float[] mTempDragBottomRightCoordinates = new float[2]; 1230280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka private Matrix mTempInverseMatrix = new Matrix(); 12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 125d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static final int DEFAULT_CELL_COUNT_X = 4; 126d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static final int DEFAULT_CELL_COUNT_Y = 4; 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1288a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy private Drawable mPreviousIndicator; 1298a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy private Drawable mNextIndicator; 130aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1311262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy // State variable that indicates whether the pages are small (ie when you're 132dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // in all apps or customize mode) 133c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka private boolean mIsSmall = false; 134c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka private boolean mIsInUnshrinkAnimation = false; 135b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase private AnimatorListener mUnshrinkAnimationListener; 1363e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private enum ShrinkPosition { 1373e7c7634531302271270c8cf418abc959d621cbcMichael Jurka SHRINK_TO_TOP, SHRINK_TO_MIDDLE, SHRINK_TO_BOTTOM_HIDDEN, SHRINK_TO_BOTTOM_VISIBLE }; 1383e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private ShrinkPosition mShrunkenState; 139dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 1401262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy private boolean mInScrollArea = false; 1411262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1428e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private final HolographicOutlineHelper mOutlineHelper = new HolographicOutlineHelper(); 1434be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private Bitmap mDragOutline = null; 1448e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private final Rect mTempRect = new Rect(); 1458e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private final int[] mTempXY = new int[2]; 1464be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 14931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1510142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 15331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Workspace(Context context, AttributeSet attrs) { 15431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project this(context, attrs, 0); 15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 16231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param defStyle Unused. 16331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Workspace(Context context, AttributeSet attrs, int defStyle) { 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs, defStyle); 1660142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mContentIsRefreshable = false; 1675f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 1685f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka if (!LauncherApplication.isScreenXLarge()) { 1695f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mFadeInAdjacentScreens = false; 1705f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1728f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn mWallpaperManager = WallpaperManager.getInstance(context); 173aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 174aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung TypedArray a = context.obtainStyledAttributes(attrs, 175aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung R.styleable.Workspace, defStyle, 0); 176d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int cellCountX = a.getInt(R.styleable.Workspace_cellCountX, DEFAULT_CELL_COUNT_X); 177d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int cellCountY = a.getInt(R.styleable.Workspace_cellCountY, DEFAULT_CELL_COUNT_Y); 1780142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1); 17931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project a.recycle(); 18031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 181d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen LauncherModel.updateWorkspaceLayoutCells(cellCountX, cellCountY); 1820d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato setHapticFeedbackEnabled(false); 1830142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project initWorkspace(); 18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 18831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Initializes various states for this workspace. 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void initWorkspace() { 1910589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Context context = getContext(); 1920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mCurrentPage = mDefaultPage; 1930142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 1940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato LauncherApplication app = (LauncherApplication)context.getApplicationContext(); 1950589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = app.getIconCache(); 19631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 197472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mUnshrinkAnimationListener = new AnimatorListenerAdapter() { 198c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka public void onAnimationStart(Animator animation) { 199c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mIsInUnshrinkAnimation = true; 200c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka } 201b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase public void onAnimationEnd(Animator animation) { 202c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mIsInUnshrinkAnimation = false; 203dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 204dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka }; 2050142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 2060142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mSnapVelocity = 600; 20731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 20931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 210f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen protected int getScrollMode() { 211f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (LauncherApplication.isScreenXLarge()) { 212f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen return SmoothPagedView.QUINTIC_MODE; 213f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } else { 214f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen return SmoothPagedView.OVERSHOOT_MODE; 215f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 216f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 217f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 218f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen @Override 21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int index, LayoutParams params) { 22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, index, params); 22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child) { 22931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child); 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int index) { 23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 24031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 24121f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 24231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, index); 24331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 24431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 24531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 24631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int width, int height) { 24731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 24831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 24931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25021f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 25131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, width, height); 25231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, LayoutParams params) { 25631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 25831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 26031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, params); 26131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return The open folder on the current screen, or null if there is none 26531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Folder getOpenFolder() { 2670142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout currentPage = (CellLayout) getChildAt(mCurrentPage); 2680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int count = currentPage.getChildCount(); 26931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 2700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka View child = currentPage.getChildAt(i); 271aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (child instanceof Folder) { 272aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Folder folder = (Folder) child; 273aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder.getInfo().opened) 274aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung return folder; 27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ArrayList<Folder> getOpenFolders() { 281dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 282dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka ArrayList<Folder> folders = new ArrayList<Folder>(screenCount); 28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 284dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int screen = 0; screen < screenCount; screen++) { 2850142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout currentPage = (CellLayout) getChildAt(screen); 2860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int count = currentPage.getChildCount(); 28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 2880142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka View child = currentPage.getChildAt(i); 289aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (child instanceof Folder) { 290aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Folder folder = (Folder) child; 291aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder.getInfo().opened) 292aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung folders.add(folder); 29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 29631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 29731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return folders; 29931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3010142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka boolean isDefaultPageShowing() { 3020142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return mCurrentPage == mDefaultPage; 30331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Sets the current screen. 30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 3080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param currentPage 30931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 3100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 3110142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka void setCurrentPage(int currentPage) { 3120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.setCurrentPage(currentPage); 3130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka updateWallpaperOffset(mScrollX); 31431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 31731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the specified screen. The position and dimension of 31831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 31931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 32031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 32131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param screen The screen in which to add the child. 32231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 32331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 32631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInScreen(View child, int screen, int x, int y, int spanX, int spanY) { 32831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project addInScreen(child, screen, x, y, spanX, spanY, false); 32931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 331aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung void addInFullScreen(View child, int screen) { 332aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung addInScreen(child, screen, 0, 0, -1, -1); 333aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 334aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 33531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 33631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the specified screen. The position and dimension of 33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 33931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 34031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param screen The screen in which to add the child. 34131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 34231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 34431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 34531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param insert When true, the child is inserted at the beginning of the children list. 34631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 34731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInScreen(View child, int screen, int x, int y, int spanX, int spanY, boolean insert) { 34831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (screen < 0 || screen >= getChildCount()) { 349291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler Log.e(TAG, "The screen must be >= 0 and < " + getChildCount() 350291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler + " (was " + screen + "); skipping child"); 351291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler return; 35231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 35331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout group = (CellLayout) getChildAt(screen); 35531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 35631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (lp == null) { 35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp = new CellLayout.LayoutParams(x, y, spanX, spanY); 35831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 35931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellX = x; 36031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellY = y; 36131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellHSpan = spanX; 36231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellVSpan = spanY; 36331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 364aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 3656569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // Get the canonical child id to uniquely represent this view in this screen 366845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka int childId = LauncherModel.getCellLayoutChildId(-1, screen, x, y, spanX, spanY); 367f3ca3ab6958b104cbf2c2fa04add97d372a94d1cMichael Jurka boolean markCellsAsOccupied = !(child instanceof Folder); 368f3ca3ab6958b104cbf2c2fa04add97d372a94d1cMichael Jurka if (!group.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)) { 369aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // TODO: This branch occurs when the workspace is adding views 370aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // outside of the defined grid 3716569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // maybe we should be deleting these items from the LauncherModel? 372aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Log.w(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout"); 373aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 374aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 37531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof Folder)) { 3760d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato child.setHapticFeedbackEnabled(false); 37731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project child.setOnLongClickListener(mLongClickListener); 37831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 37900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (child instanceof DropTarget) { 380aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mDragController.addDropTarget((DropTarget) child); 38100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 38231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 38331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 384dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka public boolean onTouch(View v, MotionEvent event) { 385dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // this is an intercepted event being forwarded from a cell layout 386c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 3872b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy mLauncher.onWorkspaceClick((CellLayout) v); 38896226223d9849842bb2a67af051acbae9e0677d5Michael Jurka return true; 38921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } else if (!mPageMoving) { 39021f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen if (v == getChildAt(mCurrentPage - 1)) { 39121f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen snapToPage(mCurrentPage - 1); 39221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen return true; 39321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } else if (v == getChildAt(mCurrentPage + 1)) { 39421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen snapToPage(mCurrentPage + 1); 39521f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen return true; 39621f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } 397dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 398dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka return false; 3990e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka } 4000e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka 4015f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka @Override 4025f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka public boolean dispatchUnhandledMove(View focused, int direction) { 403c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 4045f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka // when the home screens are shrunken, shouldn't allow side-scrolling 4055f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return false; 4065f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4075f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return super.dispatchUnhandledMove(focused, direction); 4085f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4095f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 4105f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka @Override 4115f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka public boolean onInterceptTouchEvent(MotionEvent ev) { 412c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 4135f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka // when the home screens are shrunken, shouldn't allow side-scrolling 4145f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return false; 4155f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4165f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return super.onInterceptTouchEvent(ev); 4175f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4185f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 4191adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka @Override 4201adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka protected void determineScrollingStart(MotionEvent ev) { 4211adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) super.determineScrollingStart(ev); 4221adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka } 4231adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka 4241262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy protected void onPageBeginMoving() { 4250142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mNextPage != INVALID_PAGE) { 4260142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // we're snapping to a particular screen 42716fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka enableChildrenCache(mCurrentPage, mNextPage); 4280142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 4290142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // this is when user is actively dragging a particular screen, they might 4300142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // swipe it either left or right (but we won't advance by more than one screen) 43116fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka enableChildrenCache(mCurrentPage - 1, mCurrentPage + 1); 43231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 433f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen showOutlines(); 43421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen mPageMoving = true; 43531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 43631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4371262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy protected void onPageEndMoving() { 43816fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka clearChildrenCache(); 4391262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy // Hide the outlines, as long as we're not dragging 4401262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy if (!mDragController.dragging()) { 4411262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy hideOutlines(); 4421262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 44321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen mPageMoving = false; 4440142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4450142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4460142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 4470142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void notifyPageSwitchListener() { 4480142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.notifyPageSwitchListener(); 4490142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4500142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mPreviousIndicator != null) { 4510142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // if we know the next page, we show the indication for it right away; it looks 4520142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // weird if the indicators are lagging 4530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int page = mNextPage; 4540142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (page == INVALID_PAGE) { 4550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka page = mCurrentPage; 4560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4570142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mPreviousIndicator.setLevel(page); 4580142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mNextIndicator.setLevel(page); 4590142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 4610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka }; 4620142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4638f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private void updateWallpaperOffset() { 464798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy updateWallpaperOffset(getChildAt(getChildCount() - 1).getRight() - (mRight - mLeft)); 465798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy } 466798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy 467798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy private void updateWallpaperOffset(int scrollRange) { 46886f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung final boolean isStaticWallpaper = (mWallpaperManager != null) && 46986f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung (mWallpaperManager.getWallpaperInfo() == null); 47086f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung if (LauncherApplication.isScreenXLarge() && !isStaticWallpaper) { 47186f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung IBinder token = getWindowToken(); 47286f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung if (token != null) { 47386f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0 ); 47486f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung mWallpaperManager.setWallpaperOffsets(getWindowToken(), 47586f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung Math.max(0.f, Math.min(mScrollX/(float)scrollRange, 1.f)), 0); 47686f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung } 477956091ba7863bd72086275e61084864994dd6fa7Joe Onorato } 4788f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn } 479aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 480f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public void showOutlines() { 4813e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 4823e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeOutAnimation != null) mBackgroundFadeOutAnimation.cancel(); 4833e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeInAnimation != null) mBackgroundFadeInAnimation.cancel(); 484472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeInAnimation = ObjectAnimator.ofFloat(this, "backgroundAlpha", 1.0f); 485472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeInAnimation.setDuration(BACKGROUND_FADE_IN_DURATION); 4863e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mBackgroundFadeInAnimation.start(); 4873e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 488f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 489f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 490f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public void hideOutlines() { 4913e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 4923e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeInAnimation != null) mBackgroundFadeInAnimation.cancel(); 4933e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeOutAnimation != null) mBackgroundFadeOutAnimation.cancel(); 494472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeOutAnimation = ObjectAnimator.ofFloat(this, "backgroundAlpha", 0.0f); 495472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeOutAnimation.setDuration(BACKGROUND_FADE_OUT_DURATION); 4963e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mBackgroundFadeOutAnimation.setStartDelay(BACKGROUND_FADE_OUT_DELAY); 4973e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mBackgroundFadeOutAnimation.start(); 4983e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 499f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 500f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 501f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public void setBackgroundAlpha(float alpha) { 502f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen mBackgroundAlpha = alpha; 503f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen for (int i = 0; i < getChildCount(); i++) { 504f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen CellLayout cl = (CellLayout) getChildAt(i); 505f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setBackgroundAlpha(alpha); 506f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 507f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 508f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 509f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public float getBackgroundAlpha() { 510f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen return mBackgroundAlpha; 511f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 512f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 513f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen @Override 514f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen protected void screenScrolled(int screenCenter) { 51521f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen final int halfScreenSize = getMeasuredWidth() / 2; 51621f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen for (int i = 0; i < getChildCount(); i++) { 517f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen View v = getChildAt(i); 518f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (v != null) { 51921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen int totalDistance = v.getMeasuredWidth() + mPageSpacing; 52021f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen int delta = screenCenter - (getChildOffset(i) - 52121f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen getRelativeChildOffset(i) + halfScreenSize); 522f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 52321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen float scrollProgress = delta/(totalDistance*1.0f); 52421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen scrollProgress = Math.min(scrollProgress, 1.0f); 52521f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen scrollProgress = Math.max(scrollProgress, -1.0f); 526f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 52721f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen float rotation = WORKSPACE_ROTATION * scrollProgress; 52821f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen v.setRotationY(rotation); 529f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 530f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 531f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 532f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 53300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onAttachedToWindow() { 53400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato super.onAttachedToWindow(); 535956091ba7863bd72086275e61084864994dd6fa7Joe Onorato computeScroll(); 53600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.setWindowToken(getWindowToken()); 53700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 53800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 53931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 54028750fba6a2d141eb9a1e566718c17236030b815Michael Jurka protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 5410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.onLayout(changed, left, top, right, bottom); 542aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 54379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // if shrinkToBottom() is called on initialization, it has to be deferred 54479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // until after the first call to onLayout so that it has the correct width 54579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka if (mWaitingToShrinkToBottom) { 54679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka shrinkToBottom(false); 54779212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka mWaitingToShrinkToBottom = false; 54879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 54979212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka 550aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (LauncherApplication.isInPlaceRotationEnabled()) { 551aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // When the device is rotated, the scroll position of the current screen 552aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // needs to be refreshed 5530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(getCurrentPage()); 554aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 55531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 55631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 55731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 5580142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void dispatchDraw(Canvas canvas) { 559c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 5600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // Draw all the workspaces if we're small 5610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageCount = getChildCount(); 5620142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final long drawingTime = getDrawingTime(); 5630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka for (int i = 0; i < pageCount; i++) { 5640142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final View page = (View) getChildAt(i); 5650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 5660142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka drawChild(canvas, page, drawingTime); 5670142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 5680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 5690142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.dispatchDraw(canvas); 57031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 57131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 57231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 57331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 57431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 575678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato if (!mLauncher.isAllAppsVisible()) { 57631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Folder openFolder = getOpenFolder(); 57731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (openFolder != null) { 57831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return openFolder.requestFocus(direction, previouslyFocusedRect); 57931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 5800142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return super.onRequestFocusInDescendants(direction, previouslyFocusedRect); 58131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 58231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 58331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 58431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 58531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 58631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 587c2e24c0a37ddeab930f731c062705d435e477f75Romain Guy public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { 588678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato if (!mLauncher.isAllAppsVisible()) { 58931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Folder openFolder = getOpenFolder(); 5900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (openFolder != null) { 59131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project openFolder.addFocusables(views, direction); 5920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 5930142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.addFocusables(views, direction, focusableMode); 59431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 59531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 59631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 59731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 59831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 5997bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato public boolean dispatchTouchEvent(MotionEvent ev) { 6007bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato if (ev.getAction() == MotionEvent.ACTION_DOWN) { 60154dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka // (In XLarge mode, the workspace is shrunken below all apps, and responds to taps 60254dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka // ie when you click on a mini-screen, it zooms back to that screen) 6036b4adbc0558fcebbd44998bd00dcd334ddbee32dJoe Onorato if (!LauncherApplication.isScreenXLarge() && mLauncher.isAllAppsVisible()) { 6047bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato return false; 6057bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 6067bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 6077bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato return super.dispatchTouchEvent(ev); 6087bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 6097bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato 6100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka void enableChildrenCache(int fromPage, int toPage) { 6110142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (fromPage > toPage) { 6120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int temp = fromPage; 6130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka fromPage = toPage; 6140142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka toPage = temp; 6153a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 616aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 617dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 618fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell 6190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka fromPage = Math.max(fromPage, 0); 6200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka toPage = Math.min(toPage, screenCount - 1); 621fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell 6220142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka for (int i = fromPage; i <= toPage; i++) { 62331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 62431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawnWithCacheEnabled(true); 62531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawingCacheEnabled(true); 62631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 62731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 62831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 62931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void clearChildrenCache() { 630dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 631dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 63231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 63331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawnWithCacheEnabled(false); 63431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 63531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 63631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 63731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 63831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 6392bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (mLauncher.isAllAppsVisible()) { 6402bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato // Cancel any scrolling that is in progress. 6412bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (!mScroller.isFinished()) { 6422bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato mScroller.abortAnimation(); 6432bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato } 6443e7c7634531302271270c8cf418abc959d621cbcMichael Jurka setCurrentPage(mCurrentPage); 6457c312c15e33b6cffbda707429e88ade498fc9f5eJoe Onorato return false; // We don't want the events. Let them fall through to the all apps view. 64631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 64731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6480142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return super.onTouchEvent(ev); 64931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 650aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 65101f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka public boolean isSmall() { 65201f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka return mIsSmall; 65301f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka } 65401f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka 6556b509c1fd62a39916bb957eac07917161f549206Patrick Dubroy void shrinkToTop(boolean animated) { 6560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_TOP, animated); 65701f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka } 65801f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka 65901f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka void shrinkToMiddle() { 6600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_MIDDLE, true); 661213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 662213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 663213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka void shrinkToBottom() { 66479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka shrinkToBottom(true); 66579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 66679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka 66779212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka void shrinkToBottom(boolean animated) { 66879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka if (mFirstLayout) { 66979212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // (mFirstLayout == "first layout has not happened yet") 67079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // if we get a call to shrink() as part of our initialization (for example, if 67179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // Launcher is started in All Apps mode) then we need to wait for a layout call 67279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // to get our width so we can layout the mini-screen views correctly 67379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka mWaitingToShrinkToBottom = true; 67479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } else { 6753e7c7634531302271270c8cf418abc959d621cbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, animated); 67679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 677213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 678213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 679a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private float getYScaleForScreen(int screen) { 680a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen int x = Math.abs(screen - 2); 681a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 682a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // TODO: This should be generalized for use with arbitrary rotation angles. 683a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen switch(x) { 684a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 0: return EXTRA_SCALE_FACTOR_0; 685a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 1: return EXTRA_SCALE_FACTOR_1; 686a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 2: return EXTRA_SCALE_FACTOR_2; 687a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen } 688a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen return 1.0f; 689a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen } 690a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 691dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // we use this to shrink the workspace for the all apps view and the customize view 6920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private void shrink(ShrinkPosition shrinkPosition, boolean animated) { 693dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka mIsSmall = true; 6943e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mShrunkenState = shrinkPosition; 6953e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 6963e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // Stop any scrolling, move to the current page right away 6973e7c7634531302271270c8cf418abc959d621cbcMichael Jurka setCurrentPage(mCurrentPage); 6983e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDrops(mShrunkenState); 6993e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7005f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka // we intercept and reject all touch events when we're small, so be sure to reset the state 7015f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mTouchState = TOUCH_STATE_REST; 7025f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mActivePointerId = INVALID_POINTER; 7035f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 7047247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final Resources res = getResources(); 705dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenWidth = getWidth(); 706213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka final int screenHeight = getHeight(); 7070142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 7080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // Making the assumption that all pages have the same width as the 0th 7090142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageWidth = getChildAt(0).getMeasuredWidth(); 7100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageHeight = getChildAt(0).getMeasuredHeight(); 7110142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 7120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int scaledPageWidth = (int) (SHRINK_FACTOR * pageWidth); 7130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int scaledPageHeight = (int) (SHRINK_FACTOR * pageHeight); 714a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen final float extraScaledSpacing = res.getDimension(R.dimen.smallScreenExtraSpacing); 715dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 716dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 717a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float totalWidth = screenCount * scaledPageWidth + (screenCount - 1) * extraScaledSpacing; 718213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 719df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung boolean isPortrait = getMeasuredHeight() > getMeasuredWidth(); 720df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung float newY = (isPortrait ? 721df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung getResources().getDimension(R.dimen.smallScreenVerticalMarginPortrait) : 722df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung getResources().getDimension(R.dimen.smallScreenVerticalMarginLandscape)); 7233e7c7634531302271270c8cf418abc959d621cbcMichael Jurka float finalAlpha = 1.0f; 7243e7c7634531302271270c8cf418abc959d621cbcMichael Jurka float extraShrinkFactor = 1.0f; 7253e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (shrinkPosition == ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE) { 7263e7c7634531302271270c8cf418abc959d621cbcMichael Jurka newY = screenHeight - newY - scaledPageHeight; 7273e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) { 7283e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7293e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // We shrink and disappear to nothing in the case of all apps 7303e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // (which is when we shrink to the bottom) 7310142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka newY = screenHeight - newY - scaledPageHeight; 7323e7c7634531302271270c8cf418abc959d621cbcMichael Jurka finalAlpha = 0.0f; 7333e7c7634531302271270c8cf418abc959d621cbcMichael Jurka extraShrinkFactor = 0.1f; 7340142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_MIDDLE) { 735b0b2e6f588367cf40a4270cca81af7d78f8e382eWinson Chung newY = screenHeight / 2 - scaledPageHeight / 2; 736b0b2e6f588367cf40a4270cca81af7d78f8e382eWinson Chung finalAlpha = 1.0f; 737b0b2e6f588367cf40a4270cca81af7d78f8e382eWinson Chung } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_TOP) { 738b0b2e6f588367cf40a4270cca81af7d78f8e382eWinson Chung newY = screenHeight / 10; 739213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 740dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 741dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // We animate all the screens to the centered position in workspace 742dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // At the same time, the screens become greyed/dimmed 743dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 744dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // newX is initialized to the left-most position of the centered screens 7450142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka float newX = mScroller.getFinalX() + screenWidth / 2 - totalWidth / 2; 746a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 747a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // We are going to scale about the center of the view, so we need to adjust the positions 748a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // of the views accordingly 749a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newX -= (pageWidth - scaledPageWidth) / 2.0f; 750a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newY -= (pageHeight - scaledPageHeight) / 2.0f; 751dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 752dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka CellLayout cl = (CellLayout) getChildAt(i); 753a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 754f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen float rotation = (-i + 2) * WORKSPACE_ROTATION; 755a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float rotationScaleX = (float) (1.0f / Math.cos(Math.PI * rotation / 180.0f)); 756a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float rotationScaleY = getYScaleForScreen(i); 757a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 75879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka if (animated) { 7597247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final int duration = res.getInteger(R.integer.config_workspaceShrinkTime); 760472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(cl, 761472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("x", newX), 762472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("y", newY), 763472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("scaleX", 7643e7c7634531302271270c8cf418abc959d621cbcMichael Jurka SHRINK_FACTOR * rotationScaleX * extraShrinkFactor), 765472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("scaleY", 7663e7c7634531302271270c8cf418abc959d621cbcMichael Jurka SHRINK_FACTOR * rotationScaleY * extraShrinkFactor), 767472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("backgroundAlpha", finalAlpha), 768472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("alpha", finalAlpha), 769472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("rotationY", rotation)); 770472b281d5cb4f5660df981a6c912266b9f5703feChet Haase anim.setDuration(duration); 771472b281d5cb4f5660df981a6c912266b9f5703feChet Haase anim.start(); 77279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } else { 77379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setX((int)newX); 77479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setY((int)newY); 775f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setScaleX(SHRINK_FACTOR * rotationScaleX); 776f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setScaleY(SHRINK_FACTOR * rotationScaleY); 7775f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka cl.setBackgroundAlpha(1.0f); 7783e7c7634531302271270c8cf418abc959d621cbcMichael Jurka cl.setAlpha(finalAlpha); 779a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen cl.setRotationY(rotation); 78079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 781dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // increment newX for the next screen 782a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newX += scaledPageWidth + extraScaledSpacing; 783dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 784dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka setChildrenDrawnWithCacheEnabled(true); 785dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 786dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 7873e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7883e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private void updateWhichPagesAcceptDrops(ShrinkPosition state) { 7893e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDropsHelper(state, false, 1, 1); 7903e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 7913e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7923e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7933e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private void updateWhichPagesAcceptDropsDuringDrag(ShrinkPosition state, int spanX, int spanY) { 7943e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDropsHelper(state, true, spanX, spanY); 7953e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 7963e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7973e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private void updateWhichPagesAcceptDropsHelper( 7983e7c7634531302271270c8cf418abc959d621cbcMichael Jurka ShrinkPosition state, boolean isDragHappening, int spanX, int spanY) { 7993e7c7634531302271270c8cf418abc959d621cbcMichael Jurka final int screenCount = getChildCount(); 8003e7c7634531302271270c8cf418abc959d621cbcMichael Jurka for (int i = 0; i < screenCount; i++) { 8013e7c7634531302271270c8cf418abc959d621cbcMichael Jurka CellLayout cl = (CellLayout) getChildAt(i); 8023e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8033e7c7634531302271270c8cf418abc959d621cbcMichael Jurka switch (state) { 8043e7c7634531302271270c8cf418abc959d621cbcMichael Jurka case SHRINK_TO_TOP: 8053e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!isDragHappening) { 8063e7c7634531302271270c8cf418abc959d621cbcMichael Jurka boolean showDropHighlight = i == mCurrentPage; 8073e7c7634531302271270c8cf418abc959d621cbcMichael Jurka cl.setAcceptsDrops(showDropHighlight); 8083e7c7634531302271270c8cf418abc959d621cbcMichael Jurka break; 8093e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8103e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // otherwise, fall through below and mark non-full screens as accepting drops 8113e7c7634531302271270c8cf418abc959d621cbcMichael Jurka case SHRINK_TO_BOTTOM_HIDDEN: 8123e7c7634531302271270c8cf418abc959d621cbcMichael Jurka case SHRINK_TO_BOTTOM_VISIBLE: 8133e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!isDragHappening) { 8143e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // even if a drag isn't happening, we don't want to show a screen as 8153e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // accepting drops if it doesn't have at least one free cell 8163e7c7634531302271270c8cf418abc959d621cbcMichael Jurka spanX = 1; 8173e7c7634531302271270c8cf418abc959d621cbcMichael Jurka spanY = 1; 8183e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8193e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // the page accepts drops if we can find at least one empty spot 8203e7c7634531302271270c8cf418abc959d621cbcMichael Jurka cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY)); 8213e7c7634531302271270c8cf418abc959d621cbcMichael Jurka break; 8223e7c7634531302271270c8cf418abc959d621cbcMichael Jurka default: 8233e7c7634531302271270c8cf418abc959d621cbcMichael Jurka throw new RuntimeException( 8243e7c7634531302271270c8cf418abc959d621cbcMichael Jurka "updateWhichPagesAcceptDropsHelper passed an unhandled ShrinkPosition"); 8253e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8263e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8273e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8283e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8293e7c7634531302271270c8cf418abc959d621cbcMichael Jurka /* 8303e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * 8313e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * We call these methods (onDragStartedWithItemSpans/onDragStartedWithItemMinSize) whenever we 8323e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * start a drag in Launcher, regardless of whether the drag has ever entered the Workspace 8333e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * 8343e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * These methods mark the appropriate pages as accepting drops (which alters their visual 8353e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * appearance) and, if the pages are hidden, makes them visible. 8363e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * 8373e7c7634531302271270c8cf418abc959d621cbcMichael Jurka */ 8383e7c7634531302271270c8cf418abc959d621cbcMichael Jurka public void onDragStartedWithItemSpans(int spanX, int spanY) { 8393e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDropsDuringDrag(mShrunkenState, spanX, spanY); 8403e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) { 8413e7c7634531302271270c8cf418abc959d621cbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE, true); 8423e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8433e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8443e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8453e7c7634531302271270c8cf418abc959d621cbcMichael Jurka public void onDragStartedWithItemMinSize(int minWidth, int minHeight) { 8463e7c7634531302271270c8cf418abc959d621cbcMichael Jurka int[] spanXY = CellLayout.rectToCell(getResources(), minWidth, minHeight, null); 8473e7c7634531302271270c8cf418abc959d621cbcMichael Jurka onDragStartedWithItemSpans(spanXY[0], spanXY[1]); 8483e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8493e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8503e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // we call this method whenever a drag and drop in Launcher finishes, even if Workspace was 8513e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // never dragged over 8523e7c7634531302271270c8cf418abc959d621cbcMichael Jurka public void onDragStopped() { 8533e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDrops(mShrunkenState); 8543e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE) { 8553e7c7634531302271270c8cf418abc959d621cbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, true); 8563e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8573e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8583e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 859dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // We call this when we trigger an unshrink by clicking on the CellLayout cl 8602b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy public void unshrink(CellLayout clThatWasClicked) { 8610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int newCurrentPage = mCurrentPage; 8624cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka final int screenCount = getChildCount(); 8634cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka for (int i = 0; i < screenCount; i++) { 8644cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka if (getChildAt(i) == clThatWasClicked) { 8650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka newCurrentPage = i; 8664cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 8674cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 8680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka unshrink(newCurrentPage); 8694cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 8704cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 87121f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen @Override 87221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen protected boolean handlePagingClicks() { 87321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen return true; 87421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } 87521f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen 8760142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private void unshrink(int newCurrentPage) { 877b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka if (mIsSmall) { 8785f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int newX = getChildOffset(newCurrentPage) - getRelativeChildOffset(newCurrentPage); 8795f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int delta = newX - mScrollX; 8804cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 881b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka final int screenCount = getChildCount(); 882b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka for (int i = 0; i < screenCount; i++) { 883b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka CellLayout cl = (CellLayout) getChildAt(i); 884b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka cl.setX(cl.getX() + delta); 885b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 8860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(newCurrentPage); 887c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka unshrink(); 888b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 889dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 890dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 8914cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka void unshrink() { 8924cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka unshrink(true); 8934cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 8944cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 8954cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka void unshrink(boolean animated) { 896b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka if (mIsSmall) { 897c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mIsSmall = false; 898b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase AnimatorSet s = new AnimatorSet(); 899b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka final int screenCount = getChildCount(); 9004cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 9014cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka final int duration = getResources().getInteger(R.integer.config_workspaceUnshrinkTime); 902b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka for (int i = 0; i < screenCount; i++) { 9037247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final CellLayout cl = (CellLayout)getChildAt(i); 9045f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka float finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f; 905f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen float rotation = 0.0f; 906f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 907f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (i < mCurrentPage) { 908f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen rotation = WORKSPACE_ROTATION; 909f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } else if (i > mCurrentPage) { 910f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen rotation = -WORKSPACE_ROTATION; 911f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 912f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 9134cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka if (animated) { 914472b281d5cb4f5660df981a6c912266b9f5703feChet Haase 9154cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka s.playTogether( 916472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "translationX", 0.0f).setDuration(duration), 917472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "translationY", 0.0f).setDuration(duration), 918472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "scaleX", 1.0f).setDuration(duration), 919472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "scaleY", 1.0f).setDuration(duration), 920472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "backgroundAlpha", 0.0f).setDuration(duration), 921472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "alpha", finalAlphaValue).setDuration(duration), 922472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "rotationY", rotation).setDuration(duration)); 9234cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } else { 9244cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setTranslationX(0.0f); 9254cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setTranslationY(0.0f); 9264cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setScaleX(1.0f); 9274cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setScaleY(1.0f); 9285f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka cl.setBackgroundAlpha(0.0f); 929f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setAlpha(finalAlphaValue); 930f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setRotationY(rotation); 9314cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 932b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 933c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka if (animated) { 934c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka // If we call this when we're not animated, onAnimationEnd is never called on 935c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka // the listener; make sure we only use the listener when we're actually animating 936c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka s.addListener(mUnshrinkAnimationListener); 937c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka s.start(); 938c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka } 939dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 940dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 941dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 9424be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato /** 9434be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Draw the View v into the given Canvas. 9444be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * 9454be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * @param v the view to draw 9464be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * @param destCanvas the canvas to draw on 9474be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * @param padding the horizontal and vertical padding to use when drawing 9484be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato */ 9494be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private void drawDragView(View v, Canvas destCanvas, int padding) { 9504be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Rect clipRect = mTempRect; 9514be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato v.getDrawingRect(clipRect); 9524be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9534be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // For a TextView, adjust the clip rect so that we don't include the text label 9544be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato if (v instanceof TextView) { 9554be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int iconHeight = ((TextView)v).getCompoundPaddingTop() - v.getPaddingTop(); 9564be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato clipRect.bottom = clipRect.top + iconHeight; 9574be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 9584be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9594be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // Draw the View into the bitmap. 9604be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // The translate of scrollX and scrollY is necessary when drawing TextViews, because 9614be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // they set scrollX and scrollY to large values to achieve centered text 9624be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9634be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.save(); 9644be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.translate(-v.getScrollX() + padding / 2, -v.getScrollY() + padding / 2); 9654be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.clipRect(clipRect, Op.REPLACE); 9664be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato v.draw(destCanvas); 9674be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.restore(); 9684be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 9694be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9704be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato /** 9714be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location. 9724be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Responsibility for the bitmap is transferred to the caller. 9734be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato */ 9744be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private Bitmap createDragOutline(View v, Canvas canvas, int padding) { 9754be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int outlineColor = getResources().getColor(R.color.drag_outline_color); 9764be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Bitmap b = Bitmap.createBitmap( 9774be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato v.getWidth() + padding, v.getHeight() + padding, Bitmap.Config.ARGB_8888); 9784be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9794be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato canvas.setBitmap(b); 9804be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato drawDragView(v, canvas, padding); 9814be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true); 9824be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9834be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato return b; 9844be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 9854be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9864be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato /** 9874be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Returns a new bitmap to show when the given View is being dragged around. 9884be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Responsibility for the bitmap is transferred to the caller. 9894be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato */ 9904be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private Bitmap createDragBitmap(View v, Canvas canvas, int padding) { 9914be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int outlineColor = getResources().getColor(R.color.drag_outline_color); 9924be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Bitmap b = Bitmap.createBitmap( 9934be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mDragOutline.getWidth(), mDragOutline.getHeight(), Bitmap.Config.ARGB_8888); 9944be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 9954be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato canvas.setBitmap(b); 9964be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato canvas.drawBitmap(mDragOutline, 0, 0, null); 9974be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato drawDragView(v, canvas, padding); 9988e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy mOutlineHelper.applyOuterBlur(b, canvas, outlineColor); 9994be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10004be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato return b; 10014be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 10024be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 100331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void startDrag(CellLayout.CellInfo cellInfo) { 100431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = cellInfo.cell; 1005aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 100631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Make sure the drag was started by a long press as opposed to a long click. 10077984c9496bcaeca23ee7fdecc4d4f1bb2467e0f2Bjorn Bringert if (!child.isInTouchMode()) { 100831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 100931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1010aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 101131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = cellInfo; 10120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mDragInfo.screen = mCurrentPage; 1013aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 101408ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy CellLayout current = getCurrentDropLayout(); 101531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 101631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project current.onDragChild(child); 10174be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10184be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.clearFocus(); 10194be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.setPressed(false); 10204be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10214be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Canvas canvas = new Canvas(); 10224be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10238e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy // We need to add extra padding to the bitmap to make room for the glow effect 10248e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; 10258e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy 10264be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // The outline is used to visualize where the item will land if dropped 10278e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy mDragOutline = createDragOutline(child, canvas, bitmapPadding); 10284be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10294be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // The drag bitmap follows the touch point around on the screen 10308e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy final Bitmap b = createDragBitmap(child, canvas, bitmapPadding); 10314be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10324be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int bmpWidth = b.getWidth(); 10334be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int bmpHeight = b.getHeight(); 10344be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.getLocationOnScreen(mTempXY); 10354be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int screenX = (int) mTempXY[0] + (child.getWidth() - bmpWidth) / 2; 10364be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int screenY = (int) mTempXY[1] + (child.getHeight() - bmpHeight) / 2; 10374be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mDragController.startDrag(b, screenX, screenY, 0, 0, bmpWidth, bmpHeight, this, 10384be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.getTag(), DragController.DRAG_ACTION_MOVE, null); 10394be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato b.recycle(); 104031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 104131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10420280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka void addApplicationShortcut(ShortcutInfo info, int screen, int cellX, int cellY, 10430280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka boolean insertAtFirst, int intersectX, int intersectY) { 10440280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka final CellLayout cellLayout = (CellLayout) getChildAt(screen); 10450280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka View view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) info); 104631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10470280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka final int[] cellXY = new int[2]; 10480280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellLayout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY); 10490280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst); 10500280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka LauncherModel.addOrMoveItemInDatabase(mLauncher, info, 10510280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, 10520280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellXY[0], cellXY[1]); 105331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 105431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1055ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy private void setPositionForDropAnimation( 1056ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy View dragView, int dragViewX, int dragViewY, View parent, View child) { 1057ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 1058ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1059ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // Based on the position of the drag view, find the top left of the original view 1060ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int viewX = dragViewX + (dragView.getWidth() - child.getWidth()) / 2; 1061ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int viewY = dragViewY + (dragView.getHeight() - child.getHeight()) / 2; 1062ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy viewX -= getResources().getInteger(R.integer.config_dragViewOffsetX); 1063ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy viewY -= getResources().getInteger(R.integer.config_dragViewOffsetY); 1064ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1065ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // Set its old pos (in the new parent's coordinates); the CellLayout will 1066ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // animate it from this position during the next layout pass 1067ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy lp.oldX = viewX - (parent.getLeft() - mScrollX); 1068ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy lp.oldY = viewY - (parent.getTop() - mScrollY); 1069ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy } 10700280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 107100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, 107200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato DragView dragView, Object dragInfo) { 1073ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1074ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int originX = x - xOffset; 1075ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int originY = y - yOffset; 1076ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1077d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout == null) { 1078ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // Cancel the drag if we're not over a screen at time of drop 1079ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy if (mDragInfo != null) { 1080ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // Set its position so the parent can animate it back 1081ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy final View parent = getChildAt(mDragInfo.screen); 1082ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy setPositionForDropAnimation(dragView, originX, originY, parent, mDragInfo.cell); 1083ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy } 1084d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka return; 1085d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1086ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1087c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 10880280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // get originX and originY in the local coordinate system of the screen 10890280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mTempOriginXY[0] = originX; 10900280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mTempOriginXY[1] = originY; 1091d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mapPointFromSelfToChild(mDragTargetLayout, mTempOriginXY); 10920280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka originX = (int)mTempOriginXY[0]; 10930280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka originY = (int)mTempOriginXY[1]; 1094a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 1095c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka 109631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (source != this) { 1097d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka onDropExternal(originX, originY, dragInfo, mDragTargetLayout); 1098ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy } else if (mDragInfo != null) { 109931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Move internally 1100ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy final View cell = mDragInfo.cell; 1101ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy mTargetCell = findNearestVacantArea(originX, originY, 1102ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy mDragInfo.spanX, mDragInfo.spanY, cell, mDragTargetLayout, 1103ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy mTargetCell); 1104ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1105ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int screen = indexOfChild(mDragTargetLayout); 1106ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy if (screen != mDragInfo.screen) { 1107ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen); 1108ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy originalCellLayout.removeView(cell); 1109ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy addInScreen(cell, screen, mTargetCell[0], mTargetCell[1], 1110ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy mDragInfo.spanX, mDragInfo.spanY); 111131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1112ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy mDragTargetLayout.onDropChild(cell); 1113ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1114ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // update the item's position after drop 1115ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy final ItemInfo info = (ItemInfo) cell.getTag(); 1116ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams(); 1117ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy mDragTargetLayout.onMove(cell, mTargetCell[0], mTargetCell[1]); 1118ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy lp.cellX = mTargetCell[0]; 1119ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy lp.cellY = mTargetCell[1]; 1120ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen, 1121ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY)); 1122ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1123ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy LauncherModel.moveItemInDatabase(mLauncher, info, 1124ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, 1125ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy lp.cellX, lp.cellY); 1126ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1127ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // Prepare it to be animated into its new position 1128ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // This must be called after the view has been re-parented 1129ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy setPositionForDropAnimation(dragView, originX, originY, mDragTargetLayout, cell); 113031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 113131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 113231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1133aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void onDragEnter(DragSource source, int x, int y, int xOffset, 1134aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int yOffset, DragView dragView, Object dragInfo) { 113508ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy mDragTargetLayout = null; // Reset the drag state 113608ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy 1137d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (!mIsSmall) { 113808ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy mDragTargetLayout = getCurrentDropLayout(); 113908ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy mDragTargetLayout.onDragEnter(dragView); 1140d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka showOutlines(); 1141d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 114231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 114331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 114418014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka public DropTarget getDropTargetDelegate(DragSource source, int x, int y, 114518014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka int xOffset, int yOffset, DragView dragView, Object dragInfo) { 11466569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1147c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 1148d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // If we're shrunken, don't let anyone drag on folders/etc that are on the mini-screens 11490280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return null; 11500280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 1151440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // We may need to delegate the drag to a child view. If a 1x1 item 1152440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // would land in a cell occupied by a DragTarget (e.g. a Folder), 1153440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // then drag events should be handled by that child. 1154440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 11556569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy ItemInfo item = (ItemInfo)dragInfo; 1156440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy CellLayout currentLayout = getCurrentDropLayout(); 1157440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 1158440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy int dragPointX, dragPointY; 1159440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (item.spanX == 1 && item.spanY == 1) { 1160440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // For a 1x1, calculate the drop cell exactly as in onDragOver 1161440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointX = x - xOffset; 1162440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointY = y - yOffset; 1163440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } else { 1164440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // Otherwise, use the exact drag coordinates 1165440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointX = x; 1166440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointY = y; 1167440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 11680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka dragPointX += mScrollX - currentLayout.getLeft(); 11690280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka dragPointY += mScrollY - currentLayout.getTop(); 1170440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 1171440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // If we are dragging over a cell that contains a DropTarget that will 1172440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // accept the drop, delegate to that DropTarget. 1173440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy final int[] cellXY = mTempCell; 1174440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY); 1175440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy View child = currentLayout.getChildAt(cellXY[0], cellXY[1]); 1176440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (child instanceof DropTarget) { 1177440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy DropTarget target = (DropTarget)child; 1178440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (target.acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)) { 1179440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy return target; 1180440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 1181440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 1182440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy return null; 1183440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 11846569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 11854516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 11864516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 11874516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's 11884516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * coordinate space. The argument xy is modified with the return result. 11894516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 11904516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 11914516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka void mapPointFromSelfToChild(View v, float[] xy) { 11924516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(v, xy, null); 11934516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 11944516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 11954516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 11964516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 11974516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's 11984516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * coordinate space. The argument xy is modified with the return result. 11994516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12004516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * if cachedInverseMatrix is not null, this method will just use that matrix instead of 1201d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka * computing it itself; we use this to avoid redundant matrix inversions in 12024516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * findMatchingPageForDragOver 12034516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12044516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 12054516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka void mapPointFromSelfToChild(View v, float[] xy, Matrix cachedInverseMatrix) { 12064516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (cachedInverseMatrix == null) { 12074516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka v.getMatrix().invert(mTempInverseMatrix); 12084516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cachedInverseMatrix = mTempInverseMatrix; 12094516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 12104516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[0] = xy[0] + mScrollX - v.getLeft(); 12114516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[1] = xy[1] + mScrollY - v.getTop(); 12124516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cachedInverseMatrix.mapPoints(xy); 12134516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 12144516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 12154516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 12164516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12174516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Convert the 2D coordinate xy from this CellLayout's coordinate space to 12184516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * the parent View's coordinate space. The argument xy is modified with the return result. 12194516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12204516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 12214516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka void mapPointFromChildToSelf(View v, float[] xy) { 12224516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka v.getMatrix().mapPoints(xy); 12234516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[0] -= (mScrollX - v.getLeft()); 12244516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[1] -= (mScrollY - v.getTop()); 12254516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 12264516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 12274516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka static private float squaredDistance(float[] point1, float[] point2) { 12284516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float distanceX = point1[0] - point2[0]; 12294516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float distanceY = point2[1] - point2[1]; 12304516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return distanceX * distanceX + distanceY * distanceY; 12310280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 12320280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 12334516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 12344516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12354516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Returns true if the passed CellLayout cl overlaps with dragView 12364516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12374516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 12384516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka boolean overlaps(CellLayout cl, DragView dragView, 12394516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka int dragViewX, int dragViewY, Matrix cachedInverseMatrix) { 12404516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the coordinates of the item being dragged to the CellLayout's coordinates 12414516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] draggedItemTopLeft = mTempDragCoordinates; 12424516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemTopLeft[0] = dragViewX + dragView.getScaledDragRegionXOffset(); 12434516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemTopLeft[1] = dragViewY + dragView.getScaledDragRegionYOffset(); 12444516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] draggedItemBottomRight = mTempDragBottomRightCoordinates; 12454516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemBottomRight[0] = draggedItemTopLeft[0] + dragView.getScaledDragRegionWidth(); 12464516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemBottomRight[1] = draggedItemTopLeft[1] + dragView.getScaledDragRegionHeight(); 12474516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 12484516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the dragged item's top left coordinates 12494516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // to the CellLayout's local coordinates 12504516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(cl, draggedItemTopLeft, cachedInverseMatrix); 12514516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionLeft = Math.max(0f, draggedItemTopLeft[0]); 12524516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionTop = Math.max(0f, draggedItemTopLeft[1]); 12534516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 12544516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlapRegionLeft <= cl.getWidth() && overlapRegionTop >= 0) { 12554516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the dragged item's bottom right coordinates 12564516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // to the CellLayout's local coordinates 12574516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(cl, draggedItemBottomRight, cachedInverseMatrix); 12584516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionRight = Math.min(cl.getWidth(), draggedItemBottomRight[0]); 12594516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionBottom = Math.min(cl.getHeight(), draggedItemBottomRight[1]); 12604516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 12614516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlapRegionRight >= 0 && overlapRegionBottom <= cl.getHeight()) { 12624516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlap = (overlapRegionRight - overlapRegionLeft) * 12634516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka (overlapRegionBottom - overlapRegionTop); 12644516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlap > 0) { 12654516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return true; 12664516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 12674516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 12684516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 12694516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return false; 12704516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 1271a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 12724516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 12734516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12744516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * This method returns the CellLayout that is currently being dragged to. In order to drag 12754516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * to a CellLayout, either the touch point must be directly over the CellLayout, or as a second 12764516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * strategy, we see if the dragView is overlapping any CellLayout and choose the closest one 12774516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12784516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Return null if no CellLayout is currently being dragged over 12794516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 12804516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 12814516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka private CellLayout findMatchingPageForDragOver( 12824516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka DragView dragView, int originX, int originY, int offsetX, int offsetY) { 12834516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // We loop through all the screens (ie CellLayouts) and see which ones overlap 12844516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // with the item being dragged and then choose the one that's closest to the touch point 1285a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final int screenCount = getChildCount(); 1286a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout bestMatchingScreen = null; 12870280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka float smallestDistSoFar = Float.MAX_VALUE; 12884516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 1289a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka for (int i = 0; i < screenCount; i++) { 1290a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout cl = (CellLayout)getChildAt(i); 1291a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 12924516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] touchXy = mTempTouchCoordinates; 12934516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[0] = originX + offsetX; 12944516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[1] = originY + offsetY; 1295a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 12964516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the touch coordinates to the CellLayout's local coordinates 12974516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // If the touch point is within the bounds of the cell layout, we can return immediately 12980280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cl.getMatrix().invert(mTempInverseMatrix); 12994516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(cl, touchXy, mTempInverseMatrix); 13004516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 13014516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (touchXy[0] >= 0 && touchXy[0] <= cl.getWidth() && 13024516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[1] >= 0 && touchXy[1] <= cl.getHeight()) { 13034516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return cl; 13044516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 13054516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 13064516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlaps(cl, dragView, originX, originY, mTempInverseMatrix)) { 13074516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Get the center of the cell layout in screen coordinates 13084516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] cellLayoutCenter = mTempCellLayoutCenterCoordinates; 13094516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cellLayoutCenter[0] = cl.getWidth()/2; 13104516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cellLayoutCenter[1] = cl.getHeight()/2; 13114516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromChildToSelf(cl, cellLayoutCenter); 13124516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 13134516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[0] = originX + offsetX; 13144516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[1] = originY + offsetY; 13154516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 13164516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Calculate the distance between the center of the CellLayout 13174516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // and the touch point 13184516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float dist = squaredDistance(touchXy, cellLayoutCenter); 13194516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 13204516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (dist < smallestDistSoFar) { 13210280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka smallestDistSoFar = dist; 1322a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestMatchingScreen = cl; 1323a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 13244516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 1325a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 1326a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka return bestMatchingScreen; 1327a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 1328a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 1329440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, 1330440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy DragView dragView, Object dragInfo) { 1331d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // When touch is inside the scroll area, skip dragOver actions for the current screen 1332d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (!mInScrollArea) { 1333d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka CellLayout layout; 1334d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int originX = x - xOffset; 1335d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int originY = y - yOffset; 1336d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 1337d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka layout = findMatchingPageForDragOver( 1338d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView, originX, originY, xOffset, yOffset); 1339d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1340d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (layout != mDragTargetLayout) { 1341d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1342d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.setHover(false); 1343d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1344d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout = layout; 1345d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1346d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.setHover(true); 1347d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1348d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1349d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } else { 1350d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka layout = getCurrentDropLayout(); 1351d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1352d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka final ItemInfo item = (ItemInfo)dragInfo; 1353d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (dragInfo instanceof LauncherAppWidgetInfo) { 1354d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo)dragInfo; 1355d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1356d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (widgetInfo.spanX == -1) { 1357d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // Calculate the grid spans needed to fit this widget 1358d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int[] spans = layout.rectToCell( 1359d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka widgetInfo.minWidth, widgetInfo.minHeight, null); 1360d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka item.spanX = spans[0]; 1361d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka item.spanY = spans[1]; 1362d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1363d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1364a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 1365d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (source instanceof AllAppsPagedView) { 1366d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // This is a hack to fix the point used to determine which cell an icon from 1367d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // the all apps screen is over 1368d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (item != null && item.spanX == 1 && layout != null) { 1369d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int dragRegionLeft = (dragView.getWidth() - layout.getCellWidth()) / 2; 1370d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1371d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka originX += dragRegionLeft - dragView.getDragRegionLeft(); 1372d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (dragView.getDragRegionWidth() != layout.getCellWidth()) { 1373d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView.setDragRegion(dragView.getDragRegionLeft(), 1374d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView.getDragRegionTop(), 1375d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka layout.getCellWidth(), 1376d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView.getDragRegionHeight()); 1377d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1378d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1379a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 13801262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1381d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (layout != mDragTargetLayout) { 1382d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1383d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.onDragExit(); 1384d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1385d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka layout.onDragEnter(dragView); 1386d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout = layout; 13871262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 13886569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1389d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // only visualize the drop locations for moving icons within the home screen on 1390d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // tablet on phone, we also visualize icons dragged in from All Apps 1391d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if ((!LauncherApplication.isScreenXLarge() || source == this) 1392d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka && mDragTargetLayout != null) { 1393d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka final View child = (mDragInfo == null) ? null : mDragInfo.cell; 1394d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int localOriginX = originX - (mDragTargetLayout.getLeft() - mScrollX); 1395d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int localOriginY = originY - (mDragTargetLayout.getTop() - mScrollY); 1396d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.visualizeDropLocation(child, mDragOutline, 1397d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka localOriginX, localOriginY, item.spanX, item.spanY); 1398d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 13991262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 1400976ebec9e31643d3513f9f0de2b433d9aa186ce9Patrick Dubroy } 140131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 140231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1403aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void onDragExit(DragSource source, int x, int y, int xOffset, 1404aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int yOffset, DragView dragView, Object dragInfo) { 14056569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (mDragTargetLayout != null) { 14060280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mDragTargetLayout.onDragExit(); 14076569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 14081262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy if (!mIsPageMoving) { 14091262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy hideOutlines(); 14101262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 141108ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy clearAllHovers(); 141231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 141331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1414aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung private void onDropExternal(int x, int y, Object dragInfo, 1415aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung CellLayout cellLayout) { 141631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project onDropExternal(x, y, dragInfo, cellLayout, false); 141731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1418aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 14192b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy /** 14202b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * Add the item specified by dragInfo to the given layout. 14212b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * This is basically the equivalent of onDropExternal, except it's not initiated 14222b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * by drag and drop. 14232b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * @return true if successful 14242b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy */ 14252b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy public boolean addExternalItemToScreen(Object dragInfo, View layout) { 14262b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy CellLayout cl = (CellLayout) layout; 14272b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy ItemInfo info = (ItemInfo) dragInfo; 14282b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy 14290280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka if (cl.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) { 14302b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy onDropExternal(0, 0, dragInfo, cl, false); 14312b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy return true; 14322b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy } 14330280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.showOutOfSpaceMessage(); 14342b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy return false; 14352b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy } 14362b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy 14370280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // Drag from somewhere else 14384be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // NOTE: This can also be called when we are outside of a drag event, when we want 14394be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // to add an item to one of the workspace screens. 1440aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung private void onDropExternal(int x, int y, Object dragInfo, 1441aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung CellLayout cellLayout, boolean insertAtFirst) { 14420280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka int screen = indexOfChild(cellLayout); 14430280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka if (dragInfo instanceof PendingAddItemInfo) { 14440280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka PendingAddItemInfo info = (PendingAddItemInfo) dragInfo; 14450280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // When dragging and dropping from customization tray, we deal with creating 14460280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // widgets/shortcuts/folders in a slightly different way 14470280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka int[] touchXY = new int[2]; 14480280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka touchXY[0] = x; 14490280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka touchXY[1] = y; 14500280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka switch (info.itemType) { 14510280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 14520280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.addAppWidgetFromDrop(info.componentName, screen, touchXY); 14530280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka break; 14540280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: 14550280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY); 14560280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka break; 14570280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 14580280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.processShortcutFromDrop(info.componentName, screen, touchXY); 14590280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka break; 14600280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka default: 14610280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka throw new IllegalStateException("Unknown item type: " + info.itemType); 14620280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 14630280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellLayout.onDragExit(); 146418014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka cellLayout.animateDrop(); 14650280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return; 14660280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 14670280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 14680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // This is for other drag/drop cases, like dragging from All Apps 146931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ItemInfo info = (ItemInfo) dragInfo; 147031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1471af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka View view = null; 147231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 147331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project switch (info.itemType) { 147431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 147531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1476e48e7c1a62e6a367803dca62c8fce9de57121b0fJoe Onorato if (info.container == NO_ID && info instanceof ApplicationInfo) { 147731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Came from all apps -- make a copy 1478aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung info = new ShortcutInfo((ApplicationInfo) info); 147931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1480aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung view = mLauncher.createShortcut(R.layout.application, cellLayout, 1481aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung (ShortcutInfo) info); 148231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 148331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 148431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, 14850280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellLayout, ((UserFolderInfo) info)); 1486af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka break; 148731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project default: 14880280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka throw new IllegalStateException("Unknown item type: " + info.itemType); 148931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 149031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14916569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // If the view is null, it has already been added. 14926569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (view == null) { 14930280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellLayout.onDragExit(); 14946569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } else { 14957ded67cd64153cd41bb133a6aab11b3254b4a5d9Michael Jurka mTargetCell = findNearestVacantArea(x, y, 1, 1, null, cellLayout, mTargetCell); 1496aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung addInScreen(view, indexOfChild(cellLayout), mTargetCell[0], 1497aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mTargetCell[1], info.spanX, info.spanY, insertAtFirst); 1498aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung cellLayout.onDropChild(view); 149918014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka cellLayout.animateDrop(); 15006569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); 150131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1502af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka LauncherModel.addOrMoveItemInDatabase(mLauncher, info, 15030280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, 1504aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung lp.cellX, lp.cellY); 1505af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka } 150631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1507aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 150870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 150970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Return the current {@link CellLayout}, correctly picking the destination 151070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * screen while a scroll is in progress. 151170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 151270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private CellLayout getCurrentDropLayout() { 1513d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // if we're currently small, use findMatchingPageForDragOver instead 1514d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mIsSmall) return null; 15150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int index = mScroller.isFinished() ? mCurrentPage : mNextPage; 151670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey return (CellLayout) getChildAt(index); 151770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 151831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 151970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 15200280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * Return the current CellInfo describing our current drag; this method exists 15210280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * so that Launcher can sync this object with the correct info when the activity is created/ 15220280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * destroyed 15230280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * 15240280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka */ 15250280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka public CellLayout.CellInfo getDragInfo() { 15260280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return mDragInfo; 15270280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 15280280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 15290280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka /** 153070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * {@inheritDoc} 153170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 153270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey public boolean acceptDrop(DragSource source, int x, int y, 153300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int xOffset, int yOffset, DragView dragView, Object dragInfo) { 1534d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout == null) { 1535d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // cancel the drag if we're not over a screen at time of drop 1536d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka return false; 15370280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 1538d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1539c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final CellLayout.CellInfo dragCellInfo = mDragInfo; 1540c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final int spanX = dragCellInfo == null ? 1 : dragCellInfo.spanX; 1541c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final int spanY = dragCellInfo == null ? 1 : dragCellInfo.spanY; 15424c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy 1543c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final View ignoreView = dragCellInfo == null ? null : dragCellInfo.cell; 15444c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy 1545d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout.findCellForSpanIgnoring(null, spanX, spanY, ignoreView)) { 15460e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka return true; 15470e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka } else { 15480280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.showOutOfSpaceMessage(); 15490e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka return false; 15500e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka } 155170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 1552aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 155370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 155470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Calculate the nearest cell where the given object would be dropped. 155570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 15566a1435d78d5133b1f37274c4d358bf6d22e10229Michael Jurka private int[] findNearestVacantArea(int pixelX, int pixelY, 155770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) { 15586569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 15595f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int localPixelX = pixelX - (layout.getLeft() - mScrollX); 15605f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int localPixelY = pixelY - (layout.getTop() - mScrollY); 15616569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 156270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey // Find the best target drop location 15630280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return layout.findNearestVacantArea( 1564fc9f07d42511231a26fa182c32e2efaa0f41d478Michael Jurka localPixelX, localPixelY, spanX, spanY, ignoreView, recycle); 156570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 1566aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 15678f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy /** 15688f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy * Estimate the size that a child with the given dimensions will take in the current screen. 15698f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy */ 15708f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy void estimateChildSize(int minWidth, int minHeight, int[] result) { 15710142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka ((CellLayout)getChildAt(mCurrentPage)).estimateChildSize(minWidth, minHeight, result); 15728f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy } 15738f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy 157431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void setLauncher(Launcher launcher) { 157531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLauncher = launcher; 157631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 157731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 157800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragController(DragController dragController) { 157900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = dragController; 158031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 158131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 158231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onDropCompleted(View target, boolean success) { 1583aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (success) { 158431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (target != this && mDragInfo != null) { 158531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); 158631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project cellLayout.removeView(mDragInfo.cell); 158700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDragInfo.cell instanceof DropTarget) { 158800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.removeDropTarget((DropTarget)mDragInfo.cell); 158900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 1590aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // final Object tag = mDragInfo.cell.getTag(); 159131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1592ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy } else if (mDragInfo != null) { 1593ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy ((CellLayout) getChildAt(mDragInfo.screen)).onDropAborted(mDragInfo.cell); 159431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 159531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 15964be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mDragOutline = null; 159731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = null; 159831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 159931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16000280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka public boolean isDropEnabled() { 16010280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return true; 16020280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 16030280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 16040142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 16050142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void onRestoreInstanceState(Parcelable state) { 16060142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.onRestoreInstanceState(state); 16070142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 16080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 16090142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 16100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 161131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void scrollLeft() { 1612c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 16130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.scrollLeft(); 161431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 161531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 161631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 16170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 161831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void scrollRight() { 1619c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 16200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.scrollRight(); 162131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 162231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1623138a04170d964da9cdec228e95b976875ae52481Karl Rosaen 16241262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy @Override 16251262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy public void onEnterScrollArea(int direction) { 1626d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 1627d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mInScrollArea = true; 1628d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka final int screen = getCurrentPage() + ((direction == DragController.SCROLL_LEFT) ? -1 : 1); 1629d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (0 <= screen && screen < getChildCount()) { 1630d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka ((CellLayout) getChildAt(screen)).setHover(true); 1631d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 16321262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1633d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1634d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.onDragExit(); 1635d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout = null; 1636d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 16371262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 16381262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 16391262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 164008ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy private void clearAllHovers() { 164108ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy final int childCount = getChildCount(); 164208ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy for (int i = 0; i < childCount; i++) { 164308ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy ((CellLayout) getChildAt(i)).setHover(false); 164408ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy } 164508ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy } 164608ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy 16471262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy @Override 16481262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy public void onExitScrollArea() { 1649d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mInScrollArea) { 1650d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mInScrollArea = false; 165108ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy clearAllHovers(); 16521262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 16531262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 16541262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 165531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Folder getFolderForTag(Object tag) { 1656dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 165731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int screen = 0; screen < screenCount; screen++) { 165831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 165931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int count = currentScreen.getChildCount(); 166031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 166131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = currentScreen.getChildAt(i); 166231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 166331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) { 166431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Folder f = (Folder) child; 1665aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (f.getInfo() == tag && f.getInfo().opened) { 166631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return f; 166731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 166831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 166931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 167031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 167131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 167231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 167331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 167431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public View getViewForTag(Object tag) { 167531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int screenCount = getChildCount(); 167631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int screen = 0; screen < screenCount; screen++) { 167731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 167831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int count = currentScreen.getChildCount(); 167931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 168031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = currentScreen.getChildAt(i); 168131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (child.getTag() == tag) { 168231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return child; 168331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 168431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 168531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 168631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 168731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 168831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 168931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 169064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato void removeItems(final ArrayList<ApplicationInfo> apps) { 1691dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 16925c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final PackageManager manager = getContext().getPackageManager(); 1693629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetManager widgets = AppWidgetManager.getInstance(getContext()); 1694574d20ec84551370987dde530c27ec493bdef564Romain Guy 169564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final HashSet<String> packageNames = new HashSet<String>(); 169664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final int appCount = apps.size(); 169764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (int i = 0; i < appCount; i++) { 169864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato packageNames.add(apps.get(i).componentName.getPackageName()); 169964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 170064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato 1701dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 170231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 1703629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1704629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // Avoid ANRs by treating each screen separately 1705629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy post(new Runnable() { 1706629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy public void run() { 1707629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ArrayList<View> childrenToRemove = new ArrayList<View>(); 1708629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy childrenToRemove.clear(); 1709aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1710629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy int childCount = layout.getChildCount(); 1711629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int j = 0; j < childCount; j++) { 1712629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final View view = layout.getChildAt(j); 1713629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Object tag = view.getTag(); 1714aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 17150589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (tag instanceof ShortcutInfo) { 17160589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo info = (ShortcutInfo) tag; 1717629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Intent intent = info.intent; 1718629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ComponentName name = intent.getComponent(); 1719aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 172064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 172164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 172264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(name.getPackageName())) { 172364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 172464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato childrenToRemove.add(view); 172564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 172664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1727629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1728629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof UserFolderInfo) { 1729629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final UserFolderInfo info = (UserFolderInfo) tag; 17300589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ArrayList<ShortcutInfo> contents = info.contents; 17310589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(1); 1732629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final int contentsCount = contents.size(); 1733629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy boolean removedFromFolder = false; 1734aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1735629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int k = 0; k < contentsCount; k++) { 17360589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo appInfo = contents.get(k); 1737629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Intent intent = appInfo.intent; 1738629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ComponentName name = intent.getComponent(); 1739aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 174064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 174164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 174264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(name.getPackageName())) { 174364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato toRemove.add(appInfo); 174473013bf94f49ffbacba2b8300f6a2dd4eeebbd13Brad Fitzpatrick LauncherModel.deleteItemFromDatabase(mLauncher, appInfo); 174564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato removedFromFolder = true; 174664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 174764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1748629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1749629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1750aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1751629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy contents.removeAll(toRemove); 1752629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (removedFromFolder) { 1753629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Folder folder = getOpenFolder(); 1754aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder != null) 1755aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung folder.notifyDataSetChanged(); 1756629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1757629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof LiveFolderInfo) { 1758629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final LiveFolderInfo info = (LiveFolderInfo) tag; 1759629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Uri uri = info.uri; 1760629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ProviderInfo providerInfo = manager.resolveContentProvider( 1761629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy uri.getAuthority(), 0); 1762629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1763f11079b11e98912ed56546eaa300efd06c6eb917Joe Onorato if (providerInfo != null) { 176464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 176564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(providerInfo.packageName)) { 176664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 1767aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung childrenToRemove.add(view); 176864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 176964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1770629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1771629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof LauncherAppWidgetInfo) { 1772629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag; 1773629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetProviderInfo provider = 1774629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy widgets.getAppWidgetInfo(info.appWidgetId); 1775e1cc6c3745c9ba721b6ab888d74c9d9e1d13ea6aDaniel Sandler if (provider != null) { 177664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 177764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(provider.provider.getPackageName())) { 177864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 1779aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung childrenToRemove.add(view); 178064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 178164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1782629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1783574d20ec84551370987dde530c27ec493bdef564Romain Guy } 1784574d20ec84551370987dde530c27ec493bdef564Romain Guy } 1785aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1786629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy childCount = childrenToRemove.size(); 1787629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int j = 0; j < childCount; j++) { 1788629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy View child = childrenToRemove.get(j); 1789629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.removeViewInLayout(child); 1790629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (child instanceof DropTarget) { 1791629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mDragController.removeDropTarget((DropTarget)child); 1792629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1793574d20ec84551370987dde530c27ec493bdef564Romain Guy } 1794aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1795629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (childCount > 0) { 1796629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.requestLayout(); 1797629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.invalidate(); 17985c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 179931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1800629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy }); 180131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 180231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1803f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 180464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato void updateShortcuts(ArrayList<ApplicationInfo> apps) { 1805dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 1806dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 1807f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 1808f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project int childCount = layout.getChildCount(); 1809f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project for (int j = 0; j < childCount; j++) { 1810f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final View view = layout.getChildAt(j); 1811f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project Object tag = view.getTag(); 18120589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (tag instanceof ShortcutInfo) { 18130589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo info = (ShortcutInfo)tag; 1814f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // We need to check for ACTION_MAIN otherwise getComponent() might 1815f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // return null for some shortcuts (for instance, for shortcuts to 1816f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // web pages.) 1817f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final Intent intent = info.intent; 1818f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final ComponentName name = intent.getComponent(); 1819f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && 182064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 182164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final int appCount = apps.size(); 1822aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung for (int k = 0; k < appCount; k++) { 182364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato ApplicationInfo app = apps.get(k); 182464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (app.componentName.equals(name)) { 182564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato info.setIcon(mIconCache.getIcon(info.intent)); 182664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato ((TextView)view).setCompoundDrawablesWithIntrinsicBounds(null, 182764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato new FastBitmapDrawable(info.getIcon(mIconCache)), 182864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato null, null); 182964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 183064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1831f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1832f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1833f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1834f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1835f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1836f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 183714f122bf847e50a3e7730ccbe57abc25d086a01bJoe Onorato void moveToDefaultScreen(boolean animate) { 1838c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 1839c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mLauncher.showWorkspace(animate, (CellLayout)getChildAt(mDefaultPage)); 1840c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka } else if (animate) { 1841c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka snapToPage(mDefaultPage); 1842c45b16862918a0c6c253bba12032165b030565afJoe Onorato } else { 18430142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(mDefaultPage); 1844c45b16862918a0c6c253bba12032165b030565afJoe Onorato } 18450142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka getChildAt(mDefaultPage).requestFocus(); 184631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 184731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18488a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy void setIndicators(Drawable previous, Drawable next) { 18498a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy mPreviousIndicator = previous; 18508a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy mNextIndicator = next; 18510142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka previous.setLevel(mCurrentPage); 18520142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka next.setLevel(mCurrentPage); 18538a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy } 18548a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy 18550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 18560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public void syncPages() { 18570142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 185831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18590142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 18600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public void syncPageItems(int page) { 186131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18620142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 186331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1864