Workspace.java revision 68846fdce6c01bbe474bd0c8307e1ccaac161cbc
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 1968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport java.util.ArrayList; 2068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport java.util.HashSet; 2168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport java.util.List; 22495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell 230280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.Animator; 2468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport android.animation.Animator.AnimatorListener; 2518014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurkaimport android.animation.AnimatorListenerAdapter; 26b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.animation.AnimatorSet; 270280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.ObjectAnimator; 280280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.PropertyValuesHolder; 29cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroyimport android.animation.TimeInterpolator; 30cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroyimport android.animation.ValueAnimator; 31cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroyimport android.animation.ValueAnimator.AnimatorUpdateListener; 3268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport android.app.AlertDialog; 338f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornimport android.app.WallpaperManager; 34629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetManager; 35629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetProviderInfo; 36a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.content.ClipData; 37a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.content.ClipDescription; 38495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.content.ComponentName; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 4031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent; 41495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.content.pm.PackageManager; 425c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.content.pm.ProviderInfo; 437247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroyimport android.content.res.Resources; 4431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.TypedArray; 454be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoimport android.graphics.Bitmap; 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas; 47a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurkaimport android.graphics.Matrix; 48a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.graphics.Paint; 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Rect; 50a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.graphics.RectF; 514be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoimport android.graphics.Region.Op; 52f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.graphics.drawable.Drawable; 535c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.net.Uri; 54956091ba7863bd72086275e61084864994dd6fa7Joe Onoratoimport android.os.IBinder; 55495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.os.Parcelable; 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 57291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandlerimport android.util.Log; 58a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.view.DragEvent; 5931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.MotionEvent; 6031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View; 61cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroyimport android.view.animation.DecelerateInterpolator; 62f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.widget.TextView; 63a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungimport android.widget.Toast; 6431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport com.android.launcher.R; 6668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chungimport com.android.launcher2.InstallWidgetReceiver.WidgetMimeTypeHandlerData; 67edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 6831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 690142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * The workspace is a wide area with a wallpaper and a finite number of pages. 700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * Each page contains a number of icons, folders or widgets the user can 71aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * interact with. A workspace is meant to be used with a fixed width only. 7231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 730142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurkapublic class Workspace extends SmoothPagedView 74dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka implements DropTarget, DragSource, DragScroller, View.OnTouchListener { 75e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy @SuppressWarnings({"UnusedDeclaration"}) 763a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato private static final String TAG = "Launcher.Workspace"; 770142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 78dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // This is how much the workspace shrinks when we enter all apps or 79dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // customization mode 80dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka private static final float SHRINK_FACTOR = 0.16f; 81a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 82f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen // Y rotation to apply to the workspace screens 83f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final float WORKSPACE_ROTATION = 12.5f; 84a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 85a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // These are extra scale factors to apply to the mini home screens 86a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // so as to achieve the desired transform 871b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen private static final float EXTRA_SCALE_FACTOR_0 = 0.972f; 88a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private static final float EXTRA_SCALE_FACTOR_1 = 1.0f; 891b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen private static final float EXTRA_SCALE_FACTOR_2 = 1.10f; 90a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 91f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final int BACKGROUND_FADE_OUT_DELAY = 300; 92f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final int BACKGROUND_FADE_OUT_DURATION = 300; 93f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private static final int BACKGROUND_FADE_IN_DURATION = 100; 94f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 953e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // These animators are used to fade the background 96472b281d5cb4f5660df981a6c912266b9f5703feChet Haase private ObjectAnimator mBackgroundFadeInAnimation; 97472b281d5cb4f5660df981a6c912266b9f5703feChet Haase private ObjectAnimator mBackgroundFadeOutAnimation; 98f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen private float mBackgroundAlpha = 0; 99f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 1008f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private final WallpaperManager mWallpaperManager; 101aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1020142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private int mDefaultPage; 10331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen private boolean mPageMoving = false; 10521f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen 10631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * CellInfo for the cell that is currently being dragged 10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 10931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private CellLayout.CellInfo mDragInfo; 110aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 11170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 11270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Target drop area calculated during last acceptDrop call. 11370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 11470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private int[] mTargetCell = null; 11531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1166569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy /** 1176569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy * The CellLayout that is currently being dragged over 1186569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy */ 1196569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy private CellLayout mDragTargetLayout = null; 1206569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Launcher mLauncher; 1220589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private IconCache mIconCache; 12300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private DragController mDragController; 124aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1254516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // These are temporary variables to prevent having to allocate a new object just to 1264516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // return an (x, y) value from helper functions. Do NOT use them to maintain other state. 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int[] mTempCell = new int[2]; 12870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private int[] mTempEstimate = new int[2]; 1290280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka private float[] mTempOriginXY = new float[2]; 130a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka private float[] mTempDragCoordinates = new float[2]; 1314516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka private float[] mTempTouchCoordinates = new float[2]; 1324516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka private float[] mTempCellLayoutCenterCoordinates = new float[2]; 133a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka private float[] mTempDragBottomRightCoordinates = new float[2]; 1340280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka private Matrix mTempInverseMatrix = new Matrix(); 13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 136d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static final int DEFAULT_CELL_COUNT_X = 4; 137d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static final int DEFAULT_CELL_COUNT_Y = 4; 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1398a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy private Drawable mPreviousIndicator; 1408a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy private Drawable mNextIndicator; 141aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1421262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy // State variable that indicates whether the pages are small (ie when you're 143dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // in all apps or customize mode) 144c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka private boolean mIsSmall = false; 145c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka private boolean mIsInUnshrinkAnimation = false; 146b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase private AnimatorListener mUnshrinkAnimationListener; 1473e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private enum ShrinkPosition { 1483e7c7634531302271270c8cf418abc959d621cbcMichael Jurka SHRINK_TO_TOP, SHRINK_TO_MIDDLE, SHRINK_TO_BOTTOM_HIDDEN, SHRINK_TO_BOTTOM_VISIBLE }; 1493e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private ShrinkPosition mShrunkenState; 150883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka private boolean mWaitingToShrink = false; 151883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka private ShrinkPosition mWaitingToShrinkPosition; 1523c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka private AnimatorSet mAnimator; 153dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 1541262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy private boolean mInScrollArea = false; 1551b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen private boolean mInDragMode = false; 1561262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1578e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private final HolographicOutlineHelper mOutlineHelper = new HolographicOutlineHelper(); 1584be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private Bitmap mDragOutline = null; 1598e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private final Rect mTempRect = new Rect(); 1608e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy private final int[] mTempXY = new int[2]; 1614be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 162cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy private ValueAnimator mDropAnim = null; 163cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy private TimeInterpolator mQuintEaseOutInterpolator = new DecelerateInterpolator(2.5f); 164cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy private View mDropView = null; 165cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy private int[] mDropViewPos = new int[] { -1, -1 }; 166cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 167a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // Paint used to draw external drop outline 168a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung private final Paint mExternalDragOutlinePaint = new Paint(); 169a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1708ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy /** Used to trigger an animation as soon as the workspace stops scrolling. */ 1718ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy private Animator mAnimOnPageEndMoving = null; 1728ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy 17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 17431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 17531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 17631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1770142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 17931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Workspace(Context context, AttributeSet attrs) { 18031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project this(context, attrs, 0); 18131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 18631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1870142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 18831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param defStyle Unused. 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 19031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Workspace(Context context, AttributeSet attrs, int defStyle) { 19131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs, defStyle); 1920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mContentIsRefreshable = false; 1935f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 1945f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka if (!LauncherApplication.isScreenXLarge()) { 1955f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mFadeInAdjacentScreens = false; 1965f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 19731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1988f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn mWallpaperManager = WallpaperManager.getInstance(context); 199aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 200aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung TypedArray a = context.obtainStyledAttributes(attrs, 201aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung R.styleable.Workspace, defStyle, 0); 202d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int cellCountX = a.getInt(R.styleable.Workspace_cellCountX, DEFAULT_CELL_COUNT_X); 203d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int cellCountY = a.getInt(R.styleable.Workspace_cellCountY, DEFAULT_CELL_COUNT_Y); 2040142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1); 20531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project a.recycle(); 20631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 207d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen LauncherModel.updateWorkspaceLayoutCells(cellCountX, cellCountY); 2080d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato setHapticFeedbackEnabled(false); 2090142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project initWorkspace(); 21131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 21431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Initializes various states for this workspace. 21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 2160142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void initWorkspace() { 2170589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Context context = getContext(); 2180142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mCurrentPage = mDefaultPage; 2190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 2200589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato LauncherApplication app = (LauncherApplication)context.getApplicationContext(); 2210589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = app.getIconCache(); 222a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung mExternalDragOutlinePaint.setAntiAlias(true); 223cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy setWillNotDraw(false); 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2253c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mUnshrinkAnimationListener = new LauncherAnimatorListenerAdapter() { 2263c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka @Override 227c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka public void onAnimationStart(Animator animation) { 228c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mIsInUnshrinkAnimation = true; 229c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka } 2303c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka @Override 2313c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka public void onAnimationEndOrCancel(Animator animation) { 232c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mIsInUnshrinkAnimation = false; 233dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 234dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka }; 2350142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mSnapVelocity = 600; 23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 239f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen protected int getScrollMode() { 240f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (LauncherApplication.isScreenXLarge()) { 241f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen return SmoothPagedView.QUINTIC_MODE; 242f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } else { 243f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen return SmoothPagedView.OVERSHOOT_MODE; 244f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 245f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 246f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 247f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen @Override 24831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int index, LayoutParams params) { 24931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 25031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 25131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, index, params); 25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 25631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child) { 25831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 25931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 26031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26121f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 26231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child); 26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int index) { 26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 26831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 26931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27021f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 27131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, index); 27231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int width, int height) { 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, width, height); 28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 28431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, LayoutParams params) { 28531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 28821f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen ((CellLayout) child).setOnInterceptTouchListener(this); 28931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, params); 29031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 29131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 29231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return The open folder on the current screen, or null if there is none 29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Folder getOpenFolder() { 2960142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout currentPage = (CellLayout) getChildAt(mCurrentPage); 2970142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int count = currentPage.getChildCount(); 29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 2990142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka View child = currentPage.getChildAt(i); 300aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (child instanceof Folder) { 301aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Folder folder = (Folder) child; 302aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder.getInfo().opened) 303aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung return folder; 30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ArrayList<Folder> getOpenFolders() { 310dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 311dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka ArrayList<Folder> folders = new ArrayList<Folder>(screenCount); 31231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 313dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int screen = 0; screen < screenCount; screen++) { 3140142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout currentPage = (CellLayout) getChildAt(screen); 3150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int count = currentPage.getChildCount(); 31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 3170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka View child = currentPage.getChildAt(i); 318aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (child instanceof Folder) { 319aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Folder folder = (Folder) child; 320aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder.getInfo().opened) 321aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung folders.add(folder); 32231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 32331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 32631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return folders; 32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 32831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3290142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka boolean isDefaultPageShowing() { 3300142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return mCurrentPage == mDefaultPage; 33131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 33331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 33431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Sets the current screen. 33531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 3360142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param currentPage 33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 3380142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 3390142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka void setCurrentPage(int currentPage) { 3400142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.setCurrentPage(currentPage); 3410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka updateWallpaperOffset(mScrollX); 34231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 34431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 34531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the specified screen. The position and dimension of 34631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 34731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 34831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 34931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param screen The screen in which to add the child. 35031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 35131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 35231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 35331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 35531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInScreen(View child, int screen, int x, int y, int spanX, int spanY) { 35631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project addInScreen(child, screen, x, y, spanX, spanY, false); 35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 35831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 359aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung void addInFullScreen(View child, int screen) { 360aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung addInScreen(child, screen, 0, 0, -1, -1); 361aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 362aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 36331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 36431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the specified screen. The position and dimension of 36531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 36631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 36731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 36831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param screen The screen in which to add the child. 36931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 37031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 37131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 37231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 37331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param insert When true, the child is inserted at the beginning of the children list. 37431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 37531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInScreen(View child, int screen, int x, int y, int spanX, int spanY, boolean insert) { 37631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (screen < 0 || screen >= getChildCount()) { 377291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler Log.e(TAG, "The screen must be >= 0 and < " + getChildCount() 378291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler + " (was " + screen + "); skipping child"); 379291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler return; 38031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 38131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 38231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout group = (CellLayout) getChildAt(screen); 38331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 38431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (lp == null) { 38531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp = new CellLayout.LayoutParams(x, y, spanX, spanY); 38631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 38731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellX = x; 38831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellY = y; 38931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellHSpan = spanX; 39031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellVSpan = spanY; 39131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 392aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 3936569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // Get the canonical child id to uniquely represent this view in this screen 394845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka int childId = LauncherModel.getCellLayoutChildId(-1, screen, x, y, spanX, spanY); 395f3ca3ab6958b104cbf2c2fa04add97d372a94d1cMichael Jurka boolean markCellsAsOccupied = !(child instanceof Folder); 396f3ca3ab6958b104cbf2c2fa04add97d372a94d1cMichael Jurka if (!group.addViewToCellLayout(child, insert ? 0 : -1, childId, lp, markCellsAsOccupied)) { 397aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // TODO: This branch occurs when the workspace is adding views 398aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // outside of the defined grid 3996569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // maybe we should be deleting these items from the LauncherModel? 400aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Log.w(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout"); 401aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 402aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 40331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof Folder)) { 4040d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato child.setHapticFeedbackEnabled(false); 40531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project child.setOnLongClickListener(mLongClickListener); 40631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 40700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (child instanceof DropTarget) { 408aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mDragController.addDropTarget((DropTarget) child); 40900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 41031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 41131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 412dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka public boolean onTouch(View v, MotionEvent event) { 413dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // this is an intercepted event being forwarded from a cell layout 414c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 4152b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy mLauncher.onWorkspaceClick((CellLayout) v); 41696226223d9849842bb2a67af051acbae9e0677d5Michael Jurka return true; 41721f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } else if (!mPageMoving) { 41821f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen if (v == getChildAt(mCurrentPage - 1)) { 41921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen snapToPage(mCurrentPage - 1); 42021f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen return true; 42121f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } else if (v == getChildAt(mCurrentPage + 1)) { 42221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen snapToPage(mCurrentPage + 1); 42321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen return true; 42421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } 425dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 426dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka return false; 4270e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka } 4280e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka 4295f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka @Override 4305f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka public boolean dispatchUnhandledMove(View focused, int direction) { 431c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 4325f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka // when the home screens are shrunken, shouldn't allow side-scrolling 4335f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return false; 4345f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4355f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return super.dispatchUnhandledMove(focused, direction); 4365f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4375f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 4385f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka @Override 4395f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka public boolean onInterceptTouchEvent(MotionEvent ev) { 440c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 4415f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka // when the home screens are shrunken, shouldn't allow side-scrolling 4425f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return false; 4435f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4445f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka return super.onInterceptTouchEvent(ev); 4455f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka } 4465f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 4471adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka @Override 4481adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka protected void determineScrollingStart(MotionEvent ev) { 4491adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) super.determineScrollingStart(ev); 4501adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka } 4511adf5391a3a3d215b226adf3702019c22a99e3b1Michael Jurka 4521262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy protected void onPageBeginMoving() { 4530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mNextPage != INVALID_PAGE) { 4540142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // we're snapping to a particular screen 45516fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka enableChildrenCache(mCurrentPage, mNextPage); 4560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 4570142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // this is when user is actively dragging a particular screen, they might 4580142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // swipe it either left or right (but we won't advance by more than one screen) 45916fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka enableChildrenCache(mCurrentPage - 1, mCurrentPage + 1); 46031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 461f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen showOutlines(); 46221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen mPageMoving = true; 46331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 46431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 4651262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy protected void onPageEndMoving() { 46616fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka clearChildrenCache(); 4671262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy // Hide the outlines, as long as we're not dragging 4681262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy if (!mDragController.dragging()) { 4691262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy hideOutlines(); 4701262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 4718ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy // Check for an animation that's waiting to be started 4728ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy if (mAnimOnPageEndMoving != null) { 4738ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy mAnimOnPageEndMoving.start(); 4748ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy mAnimOnPageEndMoving = null; 4758ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy } 4768ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy 47721f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen mPageMoving = false; 4780142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4790142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4800142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 4810142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void notifyPageSwitchListener() { 4820142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.notifyPageSwitchListener(); 4830142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4840142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mPreviousIndicator != null) { 4850142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // if we know the next page, we show the indication for it right away; it looks 4860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // weird if the indicators are lagging 4870142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int page = mNextPage; 4880142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (page == INVALID_PAGE) { 4890142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka page = mCurrentPage; 4900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4910142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mPreviousIndicator.setLevel(page); 4920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mNextIndicator.setLevel(page); 4930142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4940142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 4950142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka }; 4960142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4978f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private void updateWallpaperOffset() { 498798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy updateWallpaperOffset(getChildAt(getChildCount() - 1).getRight() - (mRight - mLeft)); 499798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy } 500798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy 501798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy private void updateWallpaperOffset(int scrollRange) { 50286f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung final boolean isStaticWallpaper = (mWallpaperManager != null) && 50386f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung (mWallpaperManager.getWallpaperInfo() == null); 50486f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung if (LauncherApplication.isScreenXLarge() && !isStaticWallpaper) { 50586f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung IBinder token = getWindowToken(); 50686f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung if (token != null) { 50786f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0 ); 50886f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung mWallpaperManager.setWallpaperOffsets(getWindowToken(), 50986f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung Math.max(0.f, Math.min(mScrollX/(float)scrollRange, 1.f)), 0); 51086f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung } 511956091ba7863bd72086275e61084864994dd6fa7Joe Onorato } 5128f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn } 513aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 514f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public void showOutlines() { 5153e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 5163e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeOutAnimation != null) mBackgroundFadeOutAnimation.cancel(); 5173e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeInAnimation != null) mBackgroundFadeInAnimation.cancel(); 518472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeInAnimation = ObjectAnimator.ofFloat(this, "backgroundAlpha", 1.0f); 519472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeInAnimation.setDuration(BACKGROUND_FADE_IN_DURATION); 5203e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mBackgroundFadeInAnimation.start(); 5213e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 522f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 523f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 524f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public void hideOutlines() { 5253e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 5263e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeInAnimation != null) mBackgroundFadeInAnimation.cancel(); 5273e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mBackgroundFadeOutAnimation != null) mBackgroundFadeOutAnimation.cancel(); 528472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeOutAnimation = ObjectAnimator.ofFloat(this, "backgroundAlpha", 0.0f); 529472b281d5cb4f5660df981a6c912266b9f5703feChet Haase mBackgroundFadeOutAnimation.setDuration(BACKGROUND_FADE_OUT_DURATION); 5303e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mBackgroundFadeOutAnimation.setStartDelay(BACKGROUND_FADE_OUT_DELAY); 5313e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mBackgroundFadeOutAnimation.start(); 5323e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 533f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 534f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 535f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public void setBackgroundAlpha(float alpha) { 536f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen mBackgroundAlpha = alpha; 537f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen for (int i = 0; i < getChildCount(); i++) { 538f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen CellLayout cl = (CellLayout) getChildAt(i); 539f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setBackgroundAlpha(alpha); 540f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 541f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 542f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 543f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen public float getBackgroundAlpha() { 544f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen return mBackgroundAlpha; 545f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 546f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 547f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen @Override 548f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen protected void screenScrolled(int screenCenter) { 54921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen final int halfScreenSize = getMeasuredWidth() / 2; 55021f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen for (int i = 0; i < getChildCount(); i++) { 5511b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen CellLayout cl = (CellLayout) getChildAt(i); 5521b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen if (cl != null) { 5531b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen int totalDistance = cl.getMeasuredWidth() + mPageSpacing; 55421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen int delta = screenCenter - (getChildOffset(i) - 55521f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen getRelativeChildOffset(i) + halfScreenSize); 556f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 55721f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen float scrollProgress = delta/(totalDistance*1.0f); 55821f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen scrollProgress = Math.min(scrollProgress, 1.0f); 55921f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen scrollProgress = Math.max(scrollProgress, -1.0f); 560f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 5611b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen float mult = mInDragMode ? 1.0f : Math.abs(scrollProgress); 5621b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen cl.setBackgroundAlphaMultiplier(mult); 5631b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen 56421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen float rotation = WORKSPACE_ROTATION * scrollProgress; 5651b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen cl.setRotationY(rotation); 566f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 567f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 568f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 569f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 57000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onAttachedToWindow() { 57100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato super.onAttachedToWindow(); 572956091ba7863bd72086275e61084864994dd6fa7Joe Onorato computeScroll(); 57300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.setWindowToken(getWindowToken()); 57400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 57500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 57631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 57728750fba6a2d141eb9a1e566718c17236030b815Michael Jurka protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 5780142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.onLayout(changed, left, top, right, bottom); 579aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 58079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // if shrinkToBottom() is called on initialization, it has to be deferred 58179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // until after the first call to onLayout so that it has the correct width 582883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka if (mWaitingToShrink) { 583883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka shrink(mWaitingToShrinkPosition, false); 584883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka mWaitingToShrink = false; 58579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 58679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka 587aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (LauncherApplication.isInPlaceRotationEnabled()) { 588aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // When the device is rotated, the scroll position of the current screen 589aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // needs to be refreshed 5900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(getCurrentPage()); 591aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 59231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 59331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 59431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 5950142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void dispatchDraw(Canvas canvas) { 596c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 5970142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // Draw all the workspaces if we're small 5980142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageCount = getChildCount(); 5990142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final long drawingTime = getDrawingTime(); 6000142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka for (int i = 0; i < pageCount; i++) { 6010142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final View page = (View) getChildAt(i); 6020142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 6030142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka drawChild(canvas, page, drawingTime); 6040142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 6050142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 6060142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.dispatchDraw(canvas); 607cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 608cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy if (mDropView != null) { 6098ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy // We are animating an item that was just dropped on the home screen. 6108ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy // Render its View in the current animation position. 611cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy canvas.save(Canvas.MATRIX_SAVE_FLAG); 612cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int xPos = mDropViewPos[0] - mDropView.getScrollX(); 613cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int yPos = mDropViewPos[1] - mDropView.getScrollY(); 614cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy canvas.translate(xPos, yPos); 615cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropView.draw(canvas); 616cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy canvas.restore(); 617cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 61831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 61931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 62031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 62131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 62231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 623678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato if (!mLauncher.isAllAppsVisible()) { 62431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Folder openFolder = getOpenFolder(); 62531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (openFolder != null) { 62631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return openFolder.requestFocus(direction, previouslyFocusedRect); 62731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 6280142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return super.onRequestFocusInDescendants(direction, previouslyFocusedRect); 62931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 63031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 63131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 63231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 63331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 63431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 635c2e24c0a37ddeab930f731c062705d435e477f75Romain Guy public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { 636678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato if (!mLauncher.isAllAppsVisible()) { 63731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Folder openFolder = getOpenFolder(); 6380142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (openFolder != null) { 63931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project openFolder.addFocusables(views, direction); 6400142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 6410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.addFocusables(views, direction, focusableMode); 64231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 64331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 64431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 64531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 64631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 6477bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato public boolean dispatchTouchEvent(MotionEvent ev) { 6487bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato if (ev.getAction() == MotionEvent.ACTION_DOWN) { 64954dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka // (In XLarge mode, the workspace is shrunken below all apps, and responds to taps 65054dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka // ie when you click on a mini-screen, it zooms back to that screen) 6516b4adbc0558fcebbd44998bd00dcd334ddbee32dJoe Onorato if (!LauncherApplication.isScreenXLarge() && mLauncher.isAllAppsVisible()) { 6527bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato return false; 6537bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 6547bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 6557bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato return super.dispatchTouchEvent(ev); 6567bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 6577bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato 6580142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka void enableChildrenCache(int fromPage, int toPage) { 6590142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (fromPage > toPage) { 6600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int temp = fromPage; 6610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka fromPage = toPage; 6620142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka toPage = temp; 6633a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 664aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 665dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 666fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell 6670142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka fromPage = Math.max(fromPage, 0); 6680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka toPage = Math.min(toPage, screenCount - 1); 669fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell 6700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka for (int i = fromPage; i <= toPage; i++) { 67131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 67231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawnWithCacheEnabled(true); 67331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawingCacheEnabled(true); 67431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 67531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 67631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 67731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void clearChildrenCache() { 678dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 679dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 68031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 68131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawnWithCacheEnabled(false); 68231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 68331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 68431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 68531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 68631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 6872bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (mLauncher.isAllAppsVisible()) { 6882bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato // Cancel any scrolling that is in progress. 6892bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (!mScroller.isFinished()) { 6902bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato mScroller.abortAnimation(); 6912bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato } 6923e7c7634531302271270c8cf418abc959d621cbcMichael Jurka setCurrentPage(mCurrentPage); 6937c312c15e33b6cffbda707429e88ade498fc9f5eJoe Onorato return false; // We don't want the events. Let them fall through to the all apps view. 69431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 69531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6960142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return super.onTouchEvent(ev); 69731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 698aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 69901f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka public boolean isSmall() { 70001f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka return mIsSmall; 70101f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka } 70201f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka 7036b509c1fd62a39916bb957eac07917161f549206Patrick Dubroy void shrinkToTop(boolean animated) { 7040142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_TOP, animated); 70501f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka } 70601f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka 70701f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka void shrinkToMiddle() { 7080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_MIDDLE, true); 709213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 710213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 711213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka void shrinkToBottom() { 71279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka shrinkToBottom(true); 71379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 71479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka 71579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka void shrinkToBottom(boolean animated) { 716883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, animated); 717213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 718213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 719a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private float getYScaleForScreen(int screen) { 720a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen int x = Math.abs(screen - 2); 721a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 722a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // TODO: This should be generalized for use with arbitrary rotation angles. 723a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen switch(x) { 724a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 0: return EXTRA_SCALE_FACTOR_0; 725a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 1: return EXTRA_SCALE_FACTOR_1; 726a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 2: return EXTRA_SCALE_FACTOR_2; 727a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen } 728a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen return 1.0f; 729a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen } 730a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 731dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // we use this to shrink the workspace for the all apps view and the customize view 7320142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private void shrink(ShrinkPosition shrinkPosition, boolean animated) { 733883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka if (mFirstLayout) { 734883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka // (mFirstLayout == "first layout has not happened yet") 735883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka // if we get a call to shrink() as part of our initialization (for example, if 736883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka // Launcher is started in All Apps mode) then we need to wait for a layout call 737883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka // to get our width so we can layout the mini-screen views correctly 738883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka mWaitingToShrink = true; 739883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka mWaitingToShrinkPosition = shrinkPosition; 740883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka return; 741883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka } 742dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka mIsSmall = true; 7433e7c7634531302271270c8cf418abc959d621cbcMichael Jurka mShrunkenState = shrinkPosition; 7443e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7453e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // Stop any scrolling, move to the current page right away 746a997ac26664befbd0d5b172e36ef9e8b2c63b435Michael Jurka setCurrentPage((mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage); 7473e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDrops(mShrunkenState); 7483e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7495f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka // we intercept and reject all touch events when we're small, so be sure to reset the state 7505f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mTouchState = TOUCH_STATE_REST; 7515f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka mActivePointerId = INVALID_POINTER; 7525f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 7531b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen CellLayout currentPage = (CellLayout) getChildAt(mCurrentPage); 7541b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen currentPage.setBackgroundAlphaMultiplier(1.0f); 7551b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen 7567247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final Resources res = getResources(); 757dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenWidth = getWidth(); 758213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka final int screenHeight = getHeight(); 7590142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 7600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // Making the assumption that all pages have the same width as the 0th 7610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageWidth = getChildAt(0).getMeasuredWidth(); 7620142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageHeight = getChildAt(0).getMeasuredHeight(); 7630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 7640142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int scaledPageWidth = (int) (SHRINK_FACTOR * pageWidth); 7650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int scaledPageHeight = (int) (SHRINK_FACTOR * pageHeight); 766a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen final float extraScaledSpacing = res.getDimension(R.dimen.smallScreenExtraSpacing); 767dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 768dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 769a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float totalWidth = screenCount * scaledPageWidth + (screenCount - 1) * extraScaledSpacing; 770213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 771df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung boolean isPortrait = getMeasuredHeight() > getMeasuredWidth(); 772df4b83dd9d6380ab963c62d1f9d1312efc87cb0fWinson Chung float newY = (isPortrait ? 773ef0066b52d2754ca0553ec79613c650b5649afaaWinson Chung getResources().getDimension(R.dimen.allAppsSmallScreenVerticalMarginPortrait) : 774ef0066b52d2754ca0553ec79613c650b5649afaaWinson Chung getResources().getDimension(R.dimen.allAppsSmallScreenVerticalMarginLandscape)); 7753e7c7634531302271270c8cf418abc959d621cbcMichael Jurka float finalAlpha = 1.0f; 7763e7c7634531302271270c8cf418abc959d621cbcMichael Jurka float extraShrinkFactor = 1.0f; 7773e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (shrinkPosition == ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE) { 7783e7c7634531302271270c8cf418abc959d621cbcMichael Jurka newY = screenHeight - newY - scaledPageHeight; 7793e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) { 7803e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 7813e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // We shrink and disappear to nothing in the case of all apps 7823e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // (which is when we shrink to the bottom) 7830142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka newY = screenHeight - newY - scaledPageHeight; 7847da1025bd7f15b04cf55c79b73e94e5e1bc959d9Winson Chung finalAlpha = 0.25f; 7850142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_MIDDLE) { 786b0b2e6f588367cf40a4270cca81af7d78f8e382eWinson Chung newY = screenHeight / 2 - scaledPageHeight / 2; 787b0b2e6f588367cf40a4270cca81af7d78f8e382eWinson Chung finalAlpha = 1.0f; 788b0b2e6f588367cf40a4270cca81af7d78f8e382eWinson Chung } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_TOP) { 789ef0066b52d2754ca0553ec79613c650b5649afaaWinson Chung newY = (isPortrait ? 790ef0066b52d2754ca0553ec79613c650b5649afaaWinson Chung getResources().getDimension(R.dimen.customizeSmallScreenVerticalMarginPortrait) : 791ef0066b52d2754ca0553ec79613c650b5649afaaWinson Chung getResources().getDimension(R.dimen.customizeSmallScreenVerticalMarginLandscape)); 792213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 793dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 794dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // We animate all the screens to the centered position in workspace 795dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // At the same time, the screens become greyed/dimmed 796dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 797dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // newX is initialized to the left-most position of the centered screens 7980142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka float newX = mScroller.getFinalX() + screenWidth / 2 - totalWidth / 2; 799a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 800a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // We are going to scale about the center of the view, so we need to adjust the positions 801a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // of the views accordingly 802a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newX -= (pageWidth - scaledPageWidth) / 2.0f; 803a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newY -= (pageHeight - scaledPageHeight) / 2.0f; 8043c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka 8053c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka if (mAnimator != null) { 8063c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator.cancel(); 8073c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka } 8083c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator = new AnimatorSet(); 809dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 810dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka CellLayout cl = (CellLayout) getChildAt(i); 811a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 812f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen float rotation = (-i + 2) * WORKSPACE_ROTATION; 813a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float rotationScaleX = (float) (1.0f / Math.cos(Math.PI * rotation / 180.0f)); 814a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float rotationScaleY = getYScaleForScreen(i); 815a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 81679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka if (animated) { 8177247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final int duration = res.getInteger(R.integer.config_workspaceShrinkTime); 818472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(cl, 819472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("x", newX), 820472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("y", newY), 821472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("scaleX", 8223e7c7634531302271270c8cf418abc959d621cbcMichael Jurka SHRINK_FACTOR * rotationScaleX * extraShrinkFactor), 823472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("scaleY", 8243e7c7634531302271270c8cf418abc959d621cbcMichael Jurka SHRINK_FACTOR * rotationScaleY * extraShrinkFactor), 825472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("backgroundAlpha", finalAlpha), 826472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("alpha", finalAlpha), 827472b281d5cb4f5660df981a6c912266b9f5703feChet Haase PropertyValuesHolder.ofFloat("rotationY", rotation)); 828472b281d5cb4f5660df981a6c912266b9f5703feChet Haase anim.setDuration(duration); 8293c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator.playTogether(anim); 83079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } else { 83179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setX((int)newX); 83279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setY((int)newY); 833883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka cl.setScaleX(SHRINK_FACTOR * rotationScaleX * extraShrinkFactor); 834883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka cl.setScaleY(SHRINK_FACTOR * rotationScaleY * extraShrinkFactor); 835883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka cl.setBackgroundAlpha(finalAlpha); 8363e7c7634531302271270c8cf418abc959d621cbcMichael Jurka cl.setAlpha(finalAlpha); 837a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen cl.setRotationY(rotation); 83879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 839dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // increment newX for the next screen 840a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newX += scaledPageWidth + extraScaledSpacing; 841dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 8423c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka if (animated) { 8433c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator.start(); 8443c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka } 845dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka setChildrenDrawnWithCacheEnabled(true); 846dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 847dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 8483e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8493e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private void updateWhichPagesAcceptDrops(ShrinkPosition state) { 8503e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDropsHelper(state, false, 1, 1); 8513e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8523e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8533e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8543e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private void updateWhichPagesAcceptDropsDuringDrag(ShrinkPosition state, int spanX, int spanY) { 8553e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDropsHelper(state, true, spanX, spanY); 8563e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8573e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8583e7c7634531302271270c8cf418abc959d621cbcMichael Jurka private void updateWhichPagesAcceptDropsHelper( 8593e7c7634531302271270c8cf418abc959d621cbcMichael Jurka ShrinkPosition state, boolean isDragHappening, int spanX, int spanY) { 8603e7c7634531302271270c8cf418abc959d621cbcMichael Jurka final int screenCount = getChildCount(); 8613e7c7634531302271270c8cf418abc959d621cbcMichael Jurka for (int i = 0; i < screenCount; i++) { 8623e7c7634531302271270c8cf418abc959d621cbcMichael Jurka CellLayout cl = (CellLayout) getChildAt(i); 8633e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8643e7c7634531302271270c8cf418abc959d621cbcMichael Jurka switch (state) { 8653e7c7634531302271270c8cf418abc959d621cbcMichael Jurka case SHRINK_TO_TOP: 8663e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!isDragHappening) { 8673e7c7634531302271270c8cf418abc959d621cbcMichael Jurka boolean showDropHighlight = i == mCurrentPage; 8683e7c7634531302271270c8cf418abc959d621cbcMichael Jurka cl.setAcceptsDrops(showDropHighlight); 8693e7c7634531302271270c8cf418abc959d621cbcMichael Jurka break; 8703e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8713e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // otherwise, fall through below and mark non-full screens as accepting drops 8723e7c7634531302271270c8cf418abc959d621cbcMichael Jurka case SHRINK_TO_BOTTOM_HIDDEN: 8733e7c7634531302271270c8cf418abc959d621cbcMichael Jurka case SHRINK_TO_BOTTOM_VISIBLE: 8743e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (!isDragHappening) { 8753e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // even if a drag isn't happening, we don't want to show a screen as 8763e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // accepting drops if it doesn't have at least one free cell 8773e7c7634531302271270c8cf418abc959d621cbcMichael Jurka spanX = 1; 8783e7c7634531302271270c8cf418abc959d621cbcMichael Jurka spanY = 1; 8793e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8803e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // the page accepts drops if we can find at least one empty spot 8813e7c7634531302271270c8cf418abc959d621cbcMichael Jurka cl.setAcceptsDrops(cl.findCellForSpan(null, spanX, spanY)); 8823e7c7634531302271270c8cf418abc959d621cbcMichael Jurka break; 8833e7c7634531302271270c8cf418abc959d621cbcMichael Jurka default: 8843e7c7634531302271270c8cf418abc959d621cbcMichael Jurka throw new RuntimeException( 8853e7c7634531302271270c8cf418abc959d621cbcMichael Jurka "updateWhichPagesAcceptDropsHelper passed an unhandled ShrinkPosition"); 8863e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8873e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8883e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 8893e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 8903e7c7634531302271270c8cf418abc959d621cbcMichael Jurka /* 8913e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * 8923e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * We call these methods (onDragStartedWithItemSpans/onDragStartedWithItemMinSize) whenever we 8933e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * start a drag in Launcher, regardless of whether the drag has ever entered the Workspace 8943e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * 8953e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * These methods mark the appropriate pages as accepting drops (which alters their visual 8963e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * appearance) and, if the pages are hidden, makes them visible. 8973e7c7634531302271270c8cf418abc959d621cbcMichael Jurka * 8983e7c7634531302271270c8cf418abc959d621cbcMichael Jurka */ 8993e7c7634531302271270c8cf418abc959d621cbcMichael Jurka public void onDragStartedWithItemSpans(int spanX, int spanY) { 9003e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDropsDuringDrag(mShrunkenState, spanX, spanY); 9013e7c7634531302271270c8cf418abc959d621cbcMichael Jurka if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN) { 9023e7c7634531302271270c8cf418abc959d621cbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE, true); 9033e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 9043e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 9053e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 9063e7c7634531302271270c8cf418abc959d621cbcMichael Jurka public void onDragStartedWithItemMinSize(int minWidth, int minHeight) { 9073e7c7634531302271270c8cf418abc959d621cbcMichael Jurka int[] spanXY = CellLayout.rectToCell(getResources(), minWidth, minHeight, null); 9083e7c7634531302271270c8cf418abc959d621cbcMichael Jurka onDragStartedWithItemSpans(spanXY[0], spanXY[1]); 9093e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 9103e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 9113e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // we call this method whenever a drag and drop in Launcher finishes, even if Workspace was 9123e7c7634531302271270c8cf418abc959d621cbcMichael Jurka // never dragged over 9133e7c7634531302271270c8cf418abc959d621cbcMichael Jurka public void onDragStopped() { 9143e7c7634531302271270c8cf418abc959d621cbcMichael Jurka updateWhichPagesAcceptDrops(mShrunkenState); 9157da1025bd7f15b04cf55c79b73e94e5e1bc959d9Winson Chung if (mShrunkenState == ShrinkPosition.SHRINK_TO_BOTTOM_VISIBLE) { 9167da1025bd7f15b04cf55c79b73e94e5e1bc959d9Winson Chung shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, true); 9177da1025bd7f15b04cf55c79b73e94e5e1bc959d9Winson Chung } 9183e7c7634531302271270c8cf418abc959d621cbcMichael Jurka } 9193e7c7634531302271270c8cf418abc959d621cbcMichael Jurka 920dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // We call this when we trigger an unshrink by clicking on the CellLayout cl 9212b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy public void unshrink(CellLayout clThatWasClicked) { 9220142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int newCurrentPage = mCurrentPage; 9234cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka final int screenCount = getChildCount(); 9244cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka for (int i = 0; i < screenCount; i++) { 9254cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka if (getChildAt(i) == clThatWasClicked) { 9260142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka newCurrentPage = i; 9274cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 9284cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 9290142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka unshrink(newCurrentPage); 9304cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 9314cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 93221f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen @Override 93321f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen protected boolean handlePagingClicks() { 93421f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen return true; 93521f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen } 93621f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen 9370142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private void unshrink(int newCurrentPage) { 938b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka if (mIsSmall) { 9395f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int newX = getChildOffset(newCurrentPage) - getRelativeChildOffset(newCurrentPage); 9405f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int delta = newX - mScrollX; 9414cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 942b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka final int screenCount = getChildCount(); 943b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka for (int i = 0; i < screenCount; i++) { 944b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka CellLayout cl = (CellLayout) getChildAt(i); 945b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka cl.setX(cl.getX() + delta); 946b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 9470142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(newCurrentPage); 948c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka unshrink(); 949b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 950dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 951dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 9524cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka void unshrink() { 9534cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka unshrink(true); 9544cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 9554cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 9564cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka void unshrink(boolean animated) { 957b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka if (mIsSmall) { 958c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mIsSmall = false; 9593c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka if (mAnimator != null) { 9603c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator.cancel(); 9613c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka } 9623c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator = new AnimatorSet(); 963b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka final int screenCount = getChildCount(); 9644cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 9654cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka final int duration = getResources().getInteger(R.integer.config_workspaceUnshrinkTime); 966b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka for (int i = 0; i < screenCount; i++) { 9677247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final CellLayout cl = (CellLayout)getChildAt(i); 9685f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka float finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f; 969f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen float rotation = 0.0f; 970f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 971f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen if (i < mCurrentPage) { 972f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen rotation = WORKSPACE_ROTATION; 973f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } else if (i > mCurrentPage) { 974f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen rotation = -WORKSPACE_ROTATION; 975f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen } 976f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 9774cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka if (animated) { 9783c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator.playTogether( 979472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "translationX", 0.0f).setDuration(duration), 980472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "translationY", 0.0f).setDuration(duration), 981472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "scaleX", 1.0f).setDuration(duration), 982472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "scaleY", 1.0f).setDuration(duration), 983472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "backgroundAlpha", 0.0f).setDuration(duration), 984472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "alpha", finalAlphaValue).setDuration(duration), 985472b281d5cb4f5660df981a6c912266b9f5703feChet Haase ObjectAnimator.ofFloat(cl, "rotationY", rotation).setDuration(duration)); 9864cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } else { 9874cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setTranslationX(0.0f); 9884cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setTranslationY(0.0f); 9894cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setScaleX(1.0f); 9904cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setScaleY(1.0f); 9915f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka cl.setBackgroundAlpha(0.0f); 992f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setAlpha(finalAlphaValue); 993f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen cl.setRotationY(rotation); 9944cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 995b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 996c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka if (animated) { 997c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka // If we call this when we're not animated, onAnimationEnd is never called on 998c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka // the listener; make sure we only use the listener when we're actually animating 9993c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator.addListener(mUnshrinkAnimationListener); 10003c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka mAnimator.start(); 1001c86756c20196e5c907df01fe0fc9193ffb934082Michael Jurka } 1002dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 1003dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 1004dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 10054be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato /** 10064be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Draw the View v into the given Canvas. 10074be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * 10084be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * @param v the view to draw 10094be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * @param destCanvas the canvas to draw on 10104be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * @param padding the horizontal and vertical padding to use when drawing 10114be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato */ 10124be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private void drawDragView(View v, Canvas destCanvas, int padding) { 10134be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Rect clipRect = mTempRect; 10144be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato v.getDrawingRect(clipRect); 10154be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10164be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // For a TextView, adjust the clip rect so that we don't include the text label 10174be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato if (v instanceof TextView) { 10184be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int iconHeight = ((TextView)v).getCompoundPaddingTop() - v.getPaddingTop(); 10194be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato clipRect.bottom = clipRect.top + iconHeight; 10204be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 10214be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10224be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // Draw the View into the bitmap. 10234be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // The translate of scrollX and scrollY is necessary when drawing TextViews, because 10244be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // they set scrollX and scrollY to large values to achieve centered text 10254be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10264be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.save(); 10274be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.translate(-v.getScrollX() + padding / 2, -v.getScrollY() + padding / 2); 10284be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.clipRect(clipRect, Op.REPLACE); 10294be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato v.draw(destCanvas); 10304be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato destCanvas.restore(); 10314be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 10324be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10334be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato /** 10344be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location. 10354be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Responsibility for the bitmap is transferred to the caller. 10364be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato */ 10374be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private Bitmap createDragOutline(View v, Canvas canvas, int padding) { 10384be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int outlineColor = getResources().getColor(R.color.drag_outline_color); 10394be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Bitmap b = Bitmap.createBitmap( 10404be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato v.getWidth() + padding, v.getHeight() + padding, Bitmap.Config.ARGB_8888); 10414be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10424be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato canvas.setBitmap(b); 10434be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato drawDragView(v, canvas, padding); 10444be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true); 10454be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10464be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato return b; 10474be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 10484be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10494be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato /** 1050a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung * Creates a drag outline to represent a drop (that we don't have the actual information for 1051a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung * yet). May be changed in the future to alter the drop outline slightly depending on the 1052a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung * clip description mime data. 1053a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung */ 1054a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung private Bitmap createExternalDragOutline(Canvas canvas, int padding) { 1055a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung Resources r = getResources(); 1056a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int outlineColor = r.getColor(R.color.drag_outline_color); 1057a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int iconWidth = r.getDimensionPixelSize(R.dimen.workspace_cell_width); 1058a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int iconHeight = r.getDimensionPixelSize(R.dimen.workspace_cell_height); 1059a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int rectRadius = r.getDimensionPixelSize(R.dimen.external_drop_icon_rect_radius); 1060a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int inset = (int) (Math.min(iconWidth, iconHeight) * 0.2f); 1061a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final Bitmap b = Bitmap.createBitmap( 1062a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung iconWidth + padding, iconHeight + padding, Bitmap.Config.ARGB_8888); 1063a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1064a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung canvas.setBitmap(b); 1065a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung canvas.drawRoundRect(new RectF(inset, inset, iconWidth - inset, iconHeight - inset), 1066a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung rectRadius, rectRadius, mExternalDragOutlinePaint); 1067a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true); 1068a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1069a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung return b; 1070a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 1071a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1072a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung /** 10734be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Returns a new bitmap to show when the given View is being dragged around. 10744be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato * Responsibility for the bitmap is transferred to the caller. 10754be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato */ 10764be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato private Bitmap createDragBitmap(View v, Canvas canvas, int padding) { 10774be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int outlineColor = getResources().getColor(R.color.drag_outline_color); 10784be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Bitmap b = Bitmap.createBitmap( 10794be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mDragOutline.getWidth(), mDragOutline.getHeight(), Bitmap.Config.ARGB_8888); 10804be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10814be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato canvas.setBitmap(b); 10824be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato canvas.drawBitmap(mDragOutline, 0, 0, null); 10834be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato drawDragView(v, canvas, padding); 10848e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy mOutlineHelper.applyOuterBlur(b, canvas, outlineColor); 10854be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 10864be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato return b; 10874be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato } 10884be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 108931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void startDrag(CellLayout.CellInfo cellInfo) { 109031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = cellInfo.cell; 1091aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 109231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Make sure the drag was started by a long press as opposed to a long click. 10937984c9496bcaeca23ee7fdecc4d4f1bb2467e0f2Bjorn Bringert if (!child.isInTouchMode()) { 109431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 109531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1096aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 109731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = cellInfo; 10980142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mDragInfo.screen = mCurrentPage; 1099aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 110008ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy CellLayout current = getCurrentDropLayout(); 110131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 110231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project current.onDragChild(child); 1103cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy child.setVisibility(View.GONE); 11044be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 11054be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.clearFocus(); 11064be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.setPressed(false); 11074be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 11084be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final Canvas canvas = new Canvas(); 11094be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 11108e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy // We need to add extra padding to the bitmap to make room for the glow effect 11118e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; 11128e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy 11134be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // The outline is used to visualize where the item will land if dropped 11148e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy mDragOutline = createDragOutline(child, canvas, bitmapPadding); 11154be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 11164be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // The drag bitmap follows the touch point around on the screen 11178e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy final Bitmap b = createDragBitmap(child, canvas, bitmapPadding); 11184be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 11194be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int bmpWidth = b.getWidth(); 11204be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int bmpHeight = b.getHeight(); 11214be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.getLocationOnScreen(mTempXY); 11224be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int screenX = (int) mTempXY[0] + (child.getWidth() - bmpWidth) / 2; 11234be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato final int screenY = (int) mTempXY[1] + (child.getHeight() - bmpHeight) / 2; 11244be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mDragController.startDrag(b, screenX, screenY, 0, 0, bmpWidth, bmpHeight, this, 11254be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato child.getTag(), DragController.DRAG_ACTION_MOVE, null); 11264be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato b.recycle(); 112731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 112831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11290280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka void addApplicationShortcut(ShortcutInfo info, int screen, int cellX, int cellY, 11300280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka boolean insertAtFirst, int intersectX, int intersectY) { 11310280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka final CellLayout cellLayout = (CellLayout) getChildAt(screen); 11320280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka View view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) info); 113331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11340280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka final int[] cellXY = new int[2]; 11350280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellLayout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY); 11360280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst); 11370280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka LauncherModel.addOrMoveItemInDatabase(mLauncher, info, 11380280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, 11390280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellXY[0], cellXY[1]); 114031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 114131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1142ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy private void setPositionForDropAnimation( 1143ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy View dragView, int dragViewX, int dragViewY, View parent, View child) { 1144ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 1145ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1146ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // Based on the position of the drag view, find the top left of the original view 1147ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int viewX = dragViewX + (dragView.getWidth() - child.getWidth()) / 2; 1148ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int viewY = dragViewY + (dragView.getHeight() - child.getHeight()) / 2; 1149ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy viewX -= getResources().getInteger(R.integer.config_dragViewOffsetX); 1150ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy viewY -= getResources().getInteger(R.integer.config_dragViewOffsetY); 1151ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1152cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // Set its old pos (in the new parent's coordinates); it will be animated 1153cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // in animateViewIntoPosition after the next layout pass 1154ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy lp.oldX = viewX - (parent.getLeft() - mScrollX); 1155ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy lp.oldY = viewY - (parent.getTop() - mScrollY); 1156ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy } 11570280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 1158cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy public void animateViewIntoPosition(final View view) { 1159cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final CellLayout parent = (CellLayout) view.getParent(); 1160cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); 1161cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1162cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // Convert the animation params to be relative to the Workspace, not the CellLayout 1163cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int fromX = lp.oldX + parent.getLeft(); 1164cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int fromY = lp.oldY + parent.getTop(); 1165cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1166cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int dx = lp.x - lp.oldX; 1167cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int dy = lp.y - lp.oldY; 1168cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1169cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // Calculate the duration of the animation based on the object's distance 1170cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final float dist = (float) Math.sqrt(dx*dx + dy*dy); 1171cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final Resources res = getResources(); 1172cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final float maxDist = (float) res.getInteger(R.integer.config_dropAnimMaxDist); 11738ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy int duration = res.getInteger(R.integer.config_dropAnimMaxDuration); 11748ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy if (dist < maxDist) { 11758ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy duration *= mQuintEaseOutInterpolator.getInterpolation(dist / maxDist); 11768ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy } 1177cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1178f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy if (mDropAnim != null) { 1179f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy // This should really be end(), but that will not be called synchronously, 1180f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy // so instead we use LauncherAnimatorListenerAdapter.onAnimationEndOrCancel() 1181f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy // and call cancel() here. 1182f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy mDropAnim.cancel(); 1183f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy } 1184f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy mDropAnim = new ValueAnimator(); 1185f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy mDropAnim.setInterpolator(mQuintEaseOutInterpolator); 1186cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1187f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy // The view is invisible during the animation; we render it manually. 1188f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy mDropAnim.addListener(new LauncherAnimatorListenerAdapter() { 1189f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy public void onAnimationStart(Animator animation) { 1190f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy // Set this here so that we don't render it until the animation begins 1191f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy mDropView = view; 1192f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy } 1193f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy 1194f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy public void onAnimationEndOrCancel(Animator animation) { 1195f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy if (mDropView != null) { 1196f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy mDropView.setVisibility(View.VISIBLE); 1197f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy mDropView = null; 1198cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 1199f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy } 1200f24312876b097e25cec922edbb58334ed234dcd7Patrick Dubroy }); 12018ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy 1202cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropAnim.setDuration(duration); 1203cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropAnim.setFloatValues(0.0f, 1.0f); 1204cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropAnim.removeAllUpdateListeners(); 1205cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropAnim.addUpdateListener(new AnimatorUpdateListener() { 1206cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy public void onAnimationUpdate(ValueAnimator animation) { 1207cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final float percent = (Float) animation.getAnimatedValue(); 1208cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // Invalidate the old position 1209cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy invalidate(mDropViewPos[0], mDropViewPos[1], 1210cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropViewPos[0] + view.getWidth(), mDropViewPos[1] + view.getHeight()); 1211cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1212cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropViewPos[0] = fromX + (int) (percent * dx + 0.5f); 1213cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropViewPos[1] = fromY + (int) (percent * dy + 0.5f); 1214cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy invalidate(mDropViewPos[0], mDropViewPos[1], 1215cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDropViewPos[0] + view.getWidth(), mDropViewPos[1] + view.getHeight()); 1216cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 1217cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy }); 12188ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy 12198ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy 12208ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy view.setVisibility(View.INVISIBLE); 12218ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy 12228ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy if (!mScroller.isFinished()) { 12238ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy mAnimOnPageEndMoving = mDropAnim; 12248ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy } else { 12258ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy mDropAnim.start(); 12268ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy } 1227cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 1228cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1229cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy /** 1230cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy * {@inheritDoc} 1231cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy */ 1232cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy public boolean acceptDrop(DragSource source, int x, int y, 1233cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy int xOffset, int yOffset, DragView dragView, Object dragInfo) { 1234cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1235cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // If it's an external drop (e.g. from All Apps), check if it should be accepted 1236cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy if (source != this) { 1237cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // Don't accept the drop if we're not over a screen at time of drop 1238cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy if (mDragTargetLayout == null) { 1239cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy return false; 1240cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 1241cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1242cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final CellLayout.CellInfo dragCellInfo = mDragInfo; 1243cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int spanX = dragCellInfo == null ? 1 : dragCellInfo.spanX; 1244cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final int spanY = dragCellInfo == null ? 1 : dragCellInfo.spanY; 1245cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1246cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final View ignoreView = dragCellInfo == null ? null : dragCellInfo.cell; 1247cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1248cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // Don't accept the drop if there's no room for the item 1249cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy if (!mDragTargetLayout.findCellForSpanIgnoring(null, spanX, spanY, ignoreView)) { 1250cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mLauncher.showOutOfSpaceMessage(); 1251cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy return false; 1252cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 1253cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 1254cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy return true; 1255cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 1256cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 125700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, 125800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato DragView dragView, Object dragInfo) { 1259ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1260ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int originX = x - xOffset; 1261ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy int originY = y - yOffset; 1262ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1263c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 12640280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // get originX and originY in the local coordinate system of the screen 12650280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mTempOriginXY[0] = originX; 12660280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mTempOriginXY[1] = originY; 1267d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mapPointFromSelfToChild(mDragTargetLayout, mTempOriginXY); 12680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka originX = (int)mTempOriginXY[0]; 12690280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka originY = (int)mTempOriginXY[1]; 1270a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 1271c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka 127231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (source != this) { 1273d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka onDropExternal(originX, originY, dragInfo, mDragTargetLayout); 1274ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy } else if (mDragInfo != null) { 1275ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy final View cell = mDragInfo.cell; 1276cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy if (mDragTargetLayout != null) { 1277cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy // Move internally 1278cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mTargetCell = findNearestVacantArea(originX, originY, 1279cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mDragInfo.spanX, mDragInfo.spanY, cell, mDragTargetLayout, 1280cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy mTargetCell); 1281cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 12829438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy if (mTargetCell == null) { 12838ae3a62e2e48dfb8f860c8b6e2c7e72b9595d7aaPatrick Dubroy snapToPage(mDragInfo.screen); 12849438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy } else { 12859438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy int screen = indexOfChild(mDragTargetLayout); 12869438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy if (screen != mDragInfo.screen) { 12879438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy // Reparent the view 12889438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy ((CellLayout) getChildAt(mDragInfo.screen)).removeView(cell); 12899438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy addInScreen(cell, screen, mTargetCell[0], mTargetCell[1], 12909438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy mDragInfo.spanX, mDragInfo.spanY); 12919438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy } 1292cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 12939438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy // update the item's position after drop 12949438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy final ItemInfo info = (ItemInfo) cell.getTag(); 12959438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams(); 12969438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy mDragTargetLayout.onMove(cell, mTargetCell[0], mTargetCell[1]); 12979438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy lp.cellX = mTargetCell[0]; 12989438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy lp.cellY = mTargetCell[1]; 12999438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen, 13009438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY)); 13019438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy 13029438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy LauncherModel.moveItemInDatabase(mLauncher, info, 13039438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, 13049438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy lp.cellX, lp.cellY); 13059438336724b4f8b54c7cdc49c5f01dd9568926ebPatrick Dubroy } 130631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1307cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 1308cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy final CellLayout parent = (CellLayout) cell.getParent(); 1309ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy 1310ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // Prepare it to be animated into its new position 1311ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy // This must be called after the view has been re-parented 1312cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy setPositionForDropAnimation(dragView, originX, originY, parent, cell); 1313cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy parent.onDropChild(cell); 131431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 131531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 131631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1317aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void onDragEnter(DragSource source, int x, int y, int xOffset, 1318aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int yOffset, DragView dragView, Object dragInfo) { 131908ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy mDragTargetLayout = null; // Reset the drag state 132008ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy 1321d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (!mIsSmall) { 132208ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy mDragTargetLayout = getCurrentDropLayout(); 1323a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung mDragTargetLayout.onDragEnter(); 1324d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka showOutlines(); 13251b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen mInDragMode = true; 13261b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen CellLayout cl = (CellLayout) getChildAt(mCurrentPage); 13271b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen cl.setBackgroundAlphaMultiplier(1.0f); 1328d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 132931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 133031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 133118014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka public DropTarget getDropTargetDelegate(DragSource source, int x, int y, 133218014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka int xOffset, int yOffset, DragView dragView, Object dragInfo) { 13336569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1334c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 1335d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // If we're shrunken, don't let anyone drag on folders/etc that are on the mini-screens 13360280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return null; 13370280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 1338440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // We may need to delegate the drag to a child view. If a 1x1 item 1339440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // would land in a cell occupied by a DragTarget (e.g. a Folder), 1340440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // then drag events should be handled by that child. 1341440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 13426569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy ItemInfo item = (ItemInfo)dragInfo; 1343440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy CellLayout currentLayout = getCurrentDropLayout(); 1344440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 1345440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy int dragPointX, dragPointY; 1346440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (item.spanX == 1 && item.spanY == 1) { 1347440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // For a 1x1, calculate the drop cell exactly as in onDragOver 1348440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointX = x - xOffset; 1349440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointY = y - yOffset; 1350440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } else { 1351440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // Otherwise, use the exact drag coordinates 1352440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointX = x; 1353440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointY = y; 1354440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 13550280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka dragPointX += mScrollX - currentLayout.getLeft(); 13560280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka dragPointY += mScrollY - currentLayout.getTop(); 1357440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 1358440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // If we are dragging over a cell that contains a DropTarget that will 1359440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // accept the drop, delegate to that DropTarget. 1360440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy final int[] cellXY = mTempCell; 1361440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY); 1362440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy View child = currentLayout.getChildAt(cellXY[0], cellXY[1]); 1363440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (child instanceof DropTarget) { 1364440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy DropTarget target = (DropTarget)child; 1365440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (target.acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)) { 1366440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy return target; 1367440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 1368440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 1369440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy return null; 1370440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 13716569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1372a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung /** 1373a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung * Global drag and drop handler 1374a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung */ 1375a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung @Override 1376a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung public boolean onDragEvent(DragEvent event) { 137768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final ClipDescription desc = event.getClipDescription(); 1378a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final CellLayout layout = (CellLayout) getChildAt(mCurrentPage); 1379a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int[] pos = new int[2]; 1380a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung layout.getLocationOnScreen(pos); 1381a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // We need to offset the drag coordinates to layout coordinate space 1382a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int x = (int) event.getX() - pos[0]; 1383a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final int y = (int) event.getY() - pos[1]; 1384a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1385a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung switch (event.getAction()) { 1386a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung case DragEvent.ACTION_DRAG_STARTED: 1387a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // Check if we have enough space on this screen to add a new shortcut 1388a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung if (!layout.findCellForSpan(pos, 1, 1)) { 1389a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung Toast.makeText(mContext, mContext.getString(R.string.out_of_space), 1390a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung Toast.LENGTH_SHORT).show(); 1391a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung return false; 1392a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 1393a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 139468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // Create the drag outline 139568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // We need to add extra padding to the bitmap to make room for the glow effect 139668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final Canvas canvas = new Canvas(); 139768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS; 139868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung mDragOutline = createExternalDragOutline(canvas, bitmapPadding); 1399a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 140068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // Show the current page outlines to indicate that we can accept this drop 140168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung showOutlines(); 140268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung layout.setHover(true); 140368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung layout.onDragEnter(); 140468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1); 1405a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 140668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung return true; 1407a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung case DragEvent.ACTION_DRAG_LOCATION: 1408a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // Visualize the drop location 1409a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1); 1410a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung return true; 1411a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung case DragEvent.ACTION_DROP: 1412a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // Check if we have enough space on this screen to add a new shortcut 1413a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung if (!layout.findCellForSpan(pos, 1, 1)) { 1414a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung Toast.makeText(mContext, mContext.getString(R.string.out_of_space), 1415a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung Toast.LENGTH_SHORT).show(); 1416a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung return false; 1417a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 1418a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1419a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // Try and add any shortcuts 1420a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung int newDropCount = 0; 1421a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final LauncherModel model = mLauncher.getModel(); 1422a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung final ClipData data = event.getClipData(); 142355cef262f97749300c2f6e764da0b00cbcb78879Winson Chung 142468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // We assume that the mime types are ordered in descending importance of 142568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // representation. So we enumerate the list of mime types and alert the 142668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // user if any widgets can handle the drop. Only the most preferred 142768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // representation will be handled. 142868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung pos[0] = x; 142968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung pos[1] = y; 143068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final int mimeTypeCount = desc.getMimeTypeCount(); 143168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung for (int j = 0; j < mimeTypeCount; ++j) { 143268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final String mimeType = desc.getMimeType(j); 143368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung 143468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung if (mimeType.equals(InstallShortcutReceiver.SHORTCUT_MIMETYPE)) { 143568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final Intent intent = data.getItem(j).getIntent(); 143668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung Object info = model.infoFromShortcutIntent(mContext, intent, data.getIcon()); 143768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung onDropExternal(x, y, info, layout); 143868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung } else { 143968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final List<WidgetMimeTypeHandlerData> widgets = 144068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung model.resolveWidgetsForMimeType(mContext, mimeType); 144168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final int numWidgets = widgets.size(); 144268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung 144368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung if (numWidgets == 0) { 144468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung continue; 144568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung } else if (numWidgets == 1) { 144668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // If there is only one item, then go ahead and add and configure 144768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // that widget 144868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final AppWidgetProviderInfo widgetInfo = widgets.get(0).widgetInfo; 144968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final PendingAddWidgetInfo createInfo = 145068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung new PendingAddWidgetInfo(widgetInfo, mimeType, data); 145168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung mLauncher.addAppWidgetFromDrop(createInfo, mCurrentPage, pos); 145268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung } else if (numWidgets > 1) { 145368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // Show the widget picker dialog if there is more than one widget 145468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung // that can handle this data type 145568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final InstallWidgetReceiver.WidgetListAdapter adapter = 145668846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung new InstallWidgetReceiver.WidgetListAdapter(mLauncher, mimeType, 145768846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung data, widgets, layout, mCurrentPage, pos); 145868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung final AlertDialog.Builder builder = 145968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung new AlertDialog.Builder(mContext); 146068846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung builder.setAdapter(adapter, adapter); 146168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung builder.setCancelable(true); 146268846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung builder.setTitle(mContext.getString( 146368846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung R.string.external_drop_widget_pick_title)); 146468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung builder.setIcon(R.drawable.ic_no_applications); 146568846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung builder.show(); 146655cef262f97749300c2f6e764da0b00cbcb78879Winson Chung } 1467a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 146868846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung newDropCount++; 146968846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung break; 1470a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 1471a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1472a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // Show error message if we couldn't accept any of the items 1473a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung if (newDropCount <= 0) { 147468846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung Toast.makeText(mContext, mContext.getString(R.string.external_drop_widget_error), 1475a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung Toast.LENGTH_SHORT).show(); 1476a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 1477a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 1478a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung return true; 1479a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung case DragEvent.ACTION_DRAG_ENDED: 1480a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // Hide the page outlines after the drop 1481a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung layout.setHover(false); 1482a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung layout.onDragExit(); 1483a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung hideOutlines(); 1484a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung return true; 1485a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 1486a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung return super.onDragEvent(event); 1487a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung } 1488a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 14894516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 14904516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 14914516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's 14924516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * coordinate space. The argument xy is modified with the return result. 14934516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 14944516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 14954516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka void mapPointFromSelfToChild(View v, float[] xy) { 14964516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(v, xy, null); 14974516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 14984516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 14994516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 15004516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15014516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's 15024516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * coordinate space. The argument xy is modified with the return result. 15034516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15044516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * if cachedInverseMatrix is not null, this method will just use that matrix instead of 1505d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka * computing it itself; we use this to avoid redundant matrix inversions in 15064516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * findMatchingPageForDragOver 15074516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15084516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 15094516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka void mapPointFromSelfToChild(View v, float[] xy, Matrix cachedInverseMatrix) { 15104516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (cachedInverseMatrix == null) { 15114516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka v.getMatrix().invert(mTempInverseMatrix); 15124516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cachedInverseMatrix = mTempInverseMatrix; 15134516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 15144516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[0] = xy[0] + mScrollX - v.getLeft(); 15154516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[1] = xy[1] + mScrollY - v.getTop(); 15164516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cachedInverseMatrix.mapPoints(xy); 15174516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 15184516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 15194516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 15204516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15214516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Convert the 2D coordinate xy from this CellLayout's coordinate space to 15224516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * the parent View's coordinate space. The argument xy is modified with the return result. 15234516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15244516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 15254516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka void mapPointFromChildToSelf(View v, float[] xy) { 15264516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka v.getMatrix().mapPoints(xy); 15274516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[0] -= (mScrollX - v.getLeft()); 15284516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka xy[1] -= (mScrollY - v.getTop()); 15294516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 15304516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 15314516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka static private float squaredDistance(float[] point1, float[] point2) { 15324516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float distanceX = point1[0] - point2[0]; 15334516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float distanceY = point2[1] - point2[1]; 15344516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return distanceX * distanceX + distanceY * distanceY; 15350280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 15360280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 15374516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 15384516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15394516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Returns true if the passed CellLayout cl overlaps with dragView 15404516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15414516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 15424516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka boolean overlaps(CellLayout cl, DragView dragView, 15434516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka int dragViewX, int dragViewY, Matrix cachedInverseMatrix) { 15444516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the coordinates of the item being dragged to the CellLayout's coordinates 15454516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] draggedItemTopLeft = mTempDragCoordinates; 15464516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemTopLeft[0] = dragViewX + dragView.getScaledDragRegionXOffset(); 15474516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemTopLeft[1] = dragViewY + dragView.getScaledDragRegionYOffset(); 15484516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] draggedItemBottomRight = mTempDragBottomRightCoordinates; 15494516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemBottomRight[0] = draggedItemTopLeft[0] + dragView.getScaledDragRegionWidth(); 15504516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka draggedItemBottomRight[1] = draggedItemTopLeft[1] + dragView.getScaledDragRegionHeight(); 15514516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 15524516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the dragged item's top left coordinates 15534516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // to the CellLayout's local coordinates 15544516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(cl, draggedItemTopLeft, cachedInverseMatrix); 15554516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionLeft = Math.max(0f, draggedItemTopLeft[0]); 15564516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionTop = Math.max(0f, draggedItemTopLeft[1]); 15574516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 15584516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlapRegionLeft <= cl.getWidth() && overlapRegionTop >= 0) { 15594516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the dragged item's bottom right coordinates 15604516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // to the CellLayout's local coordinates 15614516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(cl, draggedItemBottomRight, cachedInverseMatrix); 15624516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionRight = Math.min(cl.getWidth(), draggedItemBottomRight[0]); 15634516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlapRegionBottom = Math.min(cl.getHeight(), draggedItemBottomRight[1]); 15644516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 15654516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlapRegionRight >= 0 && overlapRegionBottom <= cl.getHeight()) { 15664516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float overlap = (overlapRegionRight - overlapRegionLeft) * 15674516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka (overlapRegionBottom - overlapRegionTop); 15684516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlap > 0) { 15694516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return true; 15704516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 15714516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 15724516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 15734516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return false; 15744516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 1575a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 15764516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka /* 15774516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15784516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * This method returns the CellLayout that is currently being dragged to. In order to drag 15794516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * to a CellLayout, either the touch point must be directly over the CellLayout, or as a second 15804516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * strategy, we see if the dragView is overlapping any CellLayout and choose the closest one 15814516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15824516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * Return null if no CellLayout is currently being dragged over 15834516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka * 15844516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka */ 15854516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka private CellLayout findMatchingPageForDragOver( 15864516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka DragView dragView, int originX, int originY, int offsetX, int offsetY) { 15874516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // We loop through all the screens (ie CellLayouts) and see which ones overlap 15884516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // with the item being dragged and then choose the one that's closest to the touch point 1589a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final int screenCount = getChildCount(); 1590a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout bestMatchingScreen = null; 15910280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka float smallestDistSoFar = Float.MAX_VALUE; 15924516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 1593a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka for (int i = 0; i < screenCount; i++) { 1594a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout cl = (CellLayout)getChildAt(i); 1595a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 15964516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] touchXy = mTempTouchCoordinates; 15974516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[0] = originX + offsetX; 15984516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[1] = originY + offsetY; 1599a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 16004516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Transform the touch coordinates to the CellLayout's local coordinates 16014516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // If the touch point is within the bounds of the cell layout, we can return immediately 16020280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cl.getMatrix().invert(mTempInverseMatrix); 16034516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromSelfToChild(cl, touchXy, mTempInverseMatrix); 16044516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 16054516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (touchXy[0] >= 0 && touchXy[0] <= cl.getWidth() && 16064516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[1] >= 0 && touchXy[1] <= cl.getHeight()) { 16074516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka return cl; 16084516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 16094516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 16104516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (overlaps(cl, dragView, originX, originY, mTempInverseMatrix)) { 16114516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Get the center of the cell layout in screen coordinates 16124516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka final float[] cellLayoutCenter = mTempCellLayoutCenterCoordinates; 16134516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cellLayoutCenter[0] = cl.getWidth()/2; 16144516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka cellLayoutCenter[1] = cl.getHeight()/2; 16154516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka mapPointFromChildToSelf(cl, cellLayoutCenter); 16164516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 16174516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[0] = originX + offsetX; 16184516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka touchXy[1] = originY + offsetY; 16194516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 16204516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // Calculate the distance between the center of the CellLayout 16214516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka // and the touch point 16224516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka float dist = squaredDistance(touchXy, cellLayoutCenter); 16234516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 16244516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka if (dist < smallestDistSoFar) { 16250280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka smallestDistSoFar = dist; 1626a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestMatchingScreen = cl; 1627a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 16284516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka } 1629a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 1630a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka return bestMatchingScreen; 1631a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 1632a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 1633440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, 1634440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy DragView dragView, Object dragInfo) { 1635d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // When touch is inside the scroll area, skip dragOver actions for the current screen 1636d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (!mInScrollArea) { 1637d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka CellLayout layout; 1638d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int originX = x - xOffset; 1639d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int originY = y - yOffset; 1640d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 1641d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka layout = findMatchingPageForDragOver( 1642d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView, originX, originY, xOffset, yOffset); 1643d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1644d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (layout != mDragTargetLayout) { 1645d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1646d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.setHover(false); 1647d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1648d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout = layout; 1649d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1650d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.setHover(true); 1651d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1652d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1653d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } else { 1654d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka layout = getCurrentDropLayout(); 1655d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1656d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka final ItemInfo item = (ItemInfo)dragInfo; 1657d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (dragInfo instanceof LauncherAppWidgetInfo) { 1658d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo)dragInfo; 1659d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1660d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (widgetInfo.spanX == -1) { 1661d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // Calculate the grid spans needed to fit this widget 1662d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int[] spans = layout.rectToCell( 1663d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka widgetInfo.minWidth, widgetInfo.minHeight, null); 1664d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka item.spanX = spans[0]; 1665d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka item.spanY = spans[1]; 1666d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1667d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1668a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 1669d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (source instanceof AllAppsPagedView) { 1670d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // This is a hack to fix the point used to determine which cell an icon from 1671d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // the all apps screen is over 1672d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (item != null && item.spanX == 1 && layout != null) { 1673d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int dragRegionLeft = (dragView.getWidth() - layout.getCellWidth()) / 2; 1674d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka 1675d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka originX += dragRegionLeft - dragView.getDragRegionLeft(); 1676d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (dragView.getDragRegionWidth() != layout.getCellWidth()) { 1677d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView.setDragRegion(dragView.getDragRegionLeft(), 1678d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView.getDragRegionTop(), 1679d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka layout.getCellWidth(), 1680d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka dragView.getDragRegionHeight()); 1681d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1682d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1683a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 16841262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1685d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (layout != mDragTargetLayout) { 1686d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1687d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.onDragExit(); 1688d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 1689a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung layout.onDragEnter(); 1690d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout = layout; 16911262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 16926569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1693d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // only visualize the drop locations for moving icons within the home screen on 1694d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // tablet on phone, we also visualize icons dragged in from All Apps 1695d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if ((!LauncherApplication.isScreenXLarge() || source == this) 1696d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka && mDragTargetLayout != null) { 1697d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka final View child = (mDragInfo == null) ? null : mDragInfo.cell; 1698d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int localOriginX = originX - (mDragTargetLayout.getLeft() - mScrollX); 1699d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka int localOriginY = originY - (mDragTargetLayout.getTop() - mScrollY); 1700d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.visualizeDropLocation(child, mDragOutline, 1701d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka localOriginX, localOriginY, item.spanX, item.spanY); 1702d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 17031262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 1704976ebec9e31643d3513f9f0de2b433d9aa186ce9Patrick Dubroy } 170531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 170631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1707aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void onDragExit(DragSource source, int x, int y, int xOffset, 1708aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int yOffset, DragView dragView, Object dragInfo) { 17096569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (mDragTargetLayout != null) { 17100280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mDragTargetLayout.onDragExit(); 17116569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 17121262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy if (!mIsPageMoving) { 17131262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy hideOutlines(); 17141b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen mInDragMode = false; 17151262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 171608ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy clearAllHovers(); 171731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 171831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1719aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung private void onDropExternal(int x, int y, Object dragInfo, 1720aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung CellLayout cellLayout) { 172131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project onDropExternal(x, y, dragInfo, cellLayout, false); 172231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1723aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 17242b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy /** 17252b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * Add the item specified by dragInfo to the given layout. 17262b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * This is basically the equivalent of onDropExternal, except it's not initiated 17272b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * by drag and drop. 17282b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * @return true if successful 17292b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy */ 17302b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy public boolean addExternalItemToScreen(Object dragInfo, View layout) { 17312b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy CellLayout cl = (CellLayout) layout; 17322b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy ItemInfo info = (ItemInfo) dragInfo; 17332b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy 17340280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka if (cl.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) { 173555cef262f97749300c2f6e764da0b00cbcb78879Winson Chung onDropExternal(-1, -1, dragInfo, cl, false); 17362b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy return true; 17372b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy } 17380280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.showOutOfSpaceMessage(); 17392b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy return false; 17402b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy } 17412b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy 17420280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // Drag from somewhere else 17434be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // NOTE: This can also be called when we are outside of a drag event, when we want 17444be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato // to add an item to one of the workspace screens. 1745aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung private void onDropExternal(int x, int y, Object dragInfo, 1746aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung CellLayout cellLayout, boolean insertAtFirst) { 17470280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka int screen = indexOfChild(cellLayout); 17480280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka if (dragInfo instanceof PendingAddItemInfo) { 17490280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka PendingAddItemInfo info = (PendingAddItemInfo) dragInfo; 17500280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // When dragging and dropping from customization tray, we deal with creating 17510280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // widgets/shortcuts/folders in a slightly different way 17520280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka int[] touchXY = new int[2]; 17530280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka touchXY[0] = x; 17540280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka touchXY[1] = y; 17550280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka switch (info.itemType) { 17560280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 175755cef262f97749300c2f6e764da0b00cbcb78879Winson Chung mLauncher.addAppWidgetFromDrop((PendingAddWidgetInfo) info, screen, touchXY); 17580280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka break; 17590280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER: 17600280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY); 17610280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka break; 17620280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 17630280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka mLauncher.processShortcutFromDrop(info.componentName, screen, touchXY); 17640280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka break; 17650280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka default: 17660280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka throw new IllegalStateException("Unknown item type: " + info.itemType); 17670280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 17680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellLayout.onDragExit(); 176918014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka cellLayout.animateDrop(); 17700280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return; 17710280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 17720280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 17730280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka // This is for other drag/drop cases, like dragging from All Apps 177431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ItemInfo info = (ItemInfo) dragInfo; 177531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1776af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka View view = null; 177731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 177831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project switch (info.itemType) { 177931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 178031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1781e48e7c1a62e6a367803dca62c8fce9de57121b0fJoe Onorato if (info.container == NO_ID && info instanceof ApplicationInfo) { 178231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Came from all apps -- make a copy 1783aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung info = new ShortcutInfo((ApplicationInfo) info); 178431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1785aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung view = mLauncher.createShortcut(R.layout.application, cellLayout, 1786aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung (ShortcutInfo) info); 178731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 178831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 178931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, 1790c9a961952d1a057029874f8426b90181f6876034Michael Jurka cellLayout, (UserFolderInfo) info, mIconCache); 1791af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka break; 179231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project default: 17930280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka throw new IllegalStateException("Unknown item type: " + info.itemType); 179431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 179531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 17966569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // If the view is null, it has already been added. 17976569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (view == null) { 17980280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka cellLayout.onDragExit(); 17996569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } else { 18007ded67cd64153cd41bb133a6aab11b3254b4a5d9Michael Jurka mTargetCell = findNearestVacantArea(x, y, 1, 1, null, cellLayout, mTargetCell); 1801aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung addInScreen(view, indexOfChild(cellLayout), mTargetCell[0], 1802aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mTargetCell[1], info.spanX, info.spanY, insertAtFirst); 1803aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung cellLayout.onDropChild(view); 180418014791be2e3f41080f0bf621c618e3f096c5c7Michael Jurka cellLayout.animateDrop(); 18056569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); 180631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1807af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka LauncherModel.addOrMoveItemInDatabase(mLauncher, info, 18080280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, 1809aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung lp.cellX, lp.cellY); 1810af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka } 181131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1812aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 181370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 181470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Return the current {@link CellLayout}, correctly picking the destination 181570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * screen while a scroll is in progress. 181670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 181770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private CellLayout getCurrentDropLayout() { 1818d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka // if we're currently small, use findMatchingPageForDragOver instead 1819d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mIsSmall) return null; 18200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int index = mScroller.isFinished() ? mCurrentPage : mNextPage; 182170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey return (CellLayout) getChildAt(index); 182270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 182331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 182470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 18250280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * Return the current CellInfo describing our current drag; this method exists 18260280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * so that Launcher can sync this object with the correct info when the activity is created/ 18270280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * destroyed 18280280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka * 18290280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka */ 18300280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka public CellLayout.CellInfo getDragInfo() { 18310280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return mDragInfo; 18320280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 18330280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 18340280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka /** 183570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Calculate the nearest cell where the given object would be dropped. 183670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 18376a1435d78d5133b1f37274c4d358bf6d22e10229Michael Jurka private int[] findNearestVacantArea(int pixelX, int pixelY, 183870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) { 18396569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 18405f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int localPixelX = pixelX - (layout.getLeft() - mScrollX); 18415f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka int localPixelY = pixelY - (layout.getTop() - mScrollY); 18426569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 184370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey // Find the best target drop location 18440280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return layout.findNearestVacantArea( 1845fc9f07d42511231a26fa182c32e2efaa0f41d478Michael Jurka localPixelX, localPixelY, spanX, spanY, ignoreView, recycle); 184670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 1847aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 18488f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy /** 18498f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy * Estimate the size that a child with the given dimensions will take in the current screen. 18508f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy */ 18518f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy void estimateChildSize(int minWidth, int minHeight, int[] result) { 18520142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka ((CellLayout)getChildAt(mCurrentPage)).estimateChildSize(minWidth, minHeight, result); 18538f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy } 18548f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy 185531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void setLauncher(Launcher launcher) { 185631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLauncher = launcher; 185731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 185831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 185900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragController(DragController dragController) { 186000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = dragController; 186131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 186231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 186331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onDropCompleted(View target, boolean success) { 1864aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (success) { 186531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (target != this && mDragInfo != null) { 186631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); 186731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project cellLayout.removeView(mDragInfo.cell); 186800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDragInfo.cell instanceof DropTarget) { 186900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.removeDropTarget((DropTarget)mDragInfo.cell); 187000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 1871aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // final Object tag = mDragInfo.cell.getTag(); 187231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1873ce34a9768b01115def95f000a6a8f35870f10d3aPatrick Dubroy } else if (mDragInfo != null) { 1874cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy ((CellLayout) getChildAt(mDragInfo.screen)).onDropChild(mDragInfo.cell); 187531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 187631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18774be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato mDragOutline = null; 187831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = null; 187931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 188031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18810280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka public boolean isDropEnabled() { 18820280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka return true; 18830280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka } 18840280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka 18850142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 18860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void onRestoreInstanceState(Parcelable state) { 18870142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.onRestoreInstanceState(state); 18880142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 18890142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 18900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 18910142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 189231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void scrollLeft() { 1893c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 18940142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.scrollLeft(); 189531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 189631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 189731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18980142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 189931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void scrollRight() { 1900c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 19010142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.scrollRight(); 190231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 190331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1904138a04170d964da9cdec228e95b976875ae52481Karl Rosaen 19051262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy @Override 19061262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy public void onEnterScrollArea(int direction) { 1907d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (!mIsSmall && !mIsInUnshrinkAnimation) { 1908d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mInScrollArea = true; 1909d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka final int screen = getCurrentPage() + ((direction == DragController.SCROLL_LEFT) ? -1 : 1); 1910d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (0 <= screen && screen < getChildCount()) { 1911d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka ((CellLayout) getChildAt(screen)).setHover(true); 1912d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 19131262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1914d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mDragTargetLayout != null) { 1915d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout.onDragExit(); 1916d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mDragTargetLayout = null; 1917d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka } 19181262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 19191262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 19201262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 192108ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy private void clearAllHovers() { 192208ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy final int childCount = getChildCount(); 192308ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy for (int i = 0; i < childCount; i++) { 192408ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy ((CellLayout) getChildAt(i)).setHover(false); 192508ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy } 192608ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy } 192708ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy 19281262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy @Override 19291262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy public void onExitScrollArea() { 1930d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka if (mInScrollArea) { 1931d718d6a7ba424b600052a147e5633a201a04ccb7Michael Jurka mInScrollArea = false; 193208ae2ec4847a971ad1b19c163e3a0d6307a8ed72Patrick Dubroy clearAllHovers(); 19331262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 19341262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy } 19351262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 193631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Folder getFolderForTag(Object tag) { 1937dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 193831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int screen = 0; screen < screenCount; screen++) { 193931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 194031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int count = currentScreen.getChildCount(); 194131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 194231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = currentScreen.getChildAt(i); 194331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 194431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) { 194531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Folder f = (Folder) child; 1946aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (f.getInfo() == tag && f.getInfo().opened) { 194731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return f; 194831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 194931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 195031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 195131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 195231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 195331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 195431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 195531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public View getViewForTag(Object tag) { 195631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int screenCount = getChildCount(); 195731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int screen = 0; screen < screenCount; screen++) { 195831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 195931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int count = currentScreen.getChildCount(); 196031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 196131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = currentScreen.getChildAt(i); 196231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (child.getTag() == tag) { 196331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return child; 196431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 196531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 196631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 196731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 196831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 196931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 197031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 197164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato void removeItems(final ArrayList<ApplicationInfo> apps) { 1972dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 19735c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final PackageManager manager = getContext().getPackageManager(); 1974629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetManager widgets = AppWidgetManager.getInstance(getContext()); 1975574d20ec84551370987dde530c27ec493bdef564Romain Guy 197664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final HashSet<String> packageNames = new HashSet<String>(); 197764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final int appCount = apps.size(); 197864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (int i = 0; i < appCount; i++) { 197964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato packageNames.add(apps.get(i).componentName.getPackageName()); 198064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 198164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato 1982dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 198331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 1984629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1985629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // Avoid ANRs by treating each screen separately 1986629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy post(new Runnable() { 1987629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy public void run() { 1988629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ArrayList<View> childrenToRemove = new ArrayList<View>(); 1989629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy childrenToRemove.clear(); 1990aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1991629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy int childCount = layout.getChildCount(); 1992629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int j = 0; j < childCount; j++) { 1993629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final View view = layout.getChildAt(j); 1994629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Object tag = view.getTag(); 1995aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 19960589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (tag instanceof ShortcutInfo) { 19970589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo info = (ShortcutInfo) tag; 1998629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Intent intent = info.intent; 1999629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ComponentName name = intent.getComponent(); 2000aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 200164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 200264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 200364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(name.getPackageName())) { 200464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 200564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato childrenToRemove.add(view); 200664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 200764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 2008629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 2009629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof UserFolderInfo) { 2010629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final UserFolderInfo info = (UserFolderInfo) tag; 20110589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ArrayList<ShortcutInfo> contents = info.contents; 20120589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(1); 2013629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final int contentsCount = contents.size(); 2014629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy boolean removedFromFolder = false; 2015aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 2016629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int k = 0; k < contentsCount; k++) { 20170589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo appInfo = contents.get(k); 2018629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Intent intent = appInfo.intent; 2019629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ComponentName name = intent.getComponent(); 2020aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 202164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 202264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 202364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(name.getPackageName())) { 202464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato toRemove.add(appInfo); 202573013bf94f49ffbacba2b8300f6a2dd4eeebbd13Brad Fitzpatrick LauncherModel.deleteItemFromDatabase(mLauncher, appInfo); 202664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato removedFromFolder = true; 202764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 202864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 2029629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 2030629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 2031aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 2032629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy contents.removeAll(toRemove); 2033629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (removedFromFolder) { 2034629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Folder folder = getOpenFolder(); 2035aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder != null) 2036aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung folder.notifyDataSetChanged(); 2037629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 2038629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof LiveFolderInfo) { 2039629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final LiveFolderInfo info = (LiveFolderInfo) tag; 2040629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Uri uri = info.uri; 2041629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ProviderInfo providerInfo = manager.resolveContentProvider( 2042629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy uri.getAuthority(), 0); 2043629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 2044f11079b11e98912ed56546eaa300efd06c6eb917Joe Onorato if (providerInfo != null) { 204564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 204664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(providerInfo.packageName)) { 204764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 2048aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung childrenToRemove.add(view); 204964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 205064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 2051629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 2052629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof LauncherAppWidgetInfo) { 2053629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag; 2054629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetProviderInfo provider = 2055629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy widgets.getAppWidgetInfo(info.appWidgetId); 2056e1cc6c3745c9ba721b6ab888d74c9d9e1d13ea6aDaniel Sandler if (provider != null) { 205764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 205864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(provider.provider.getPackageName())) { 205964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 2060aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung childrenToRemove.add(view); 206164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 206264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 2063629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 2064574d20ec84551370987dde530c27ec493bdef564Romain Guy } 2065574d20ec84551370987dde530c27ec493bdef564Romain Guy } 2066aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 2067629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy childCount = childrenToRemove.size(); 2068629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int j = 0; j < childCount; j++) { 2069629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy View child = childrenToRemove.get(j); 2070629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.removeViewInLayout(child); 2071629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (child instanceof DropTarget) { 2072629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mDragController.removeDropTarget((DropTarget)child); 2073629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 2074574d20ec84551370987dde530c27ec493bdef564Romain Guy } 2075aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 2076629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (childCount > 0) { 2077629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.requestLayout(); 2078629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.invalidate(); 20795c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 208031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2081629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy }); 208231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 208331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2084f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 208564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato void updateShortcuts(ArrayList<ApplicationInfo> apps) { 2086dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 2087dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 2088f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 2089f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project int childCount = layout.getChildCount(); 2090f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project for (int j = 0; j < childCount; j++) { 2091f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final View view = layout.getChildAt(j); 2092f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project Object tag = view.getTag(); 20930589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (tag instanceof ShortcutInfo) { 20940589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo info = (ShortcutInfo)tag; 2095f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // We need to check for ACTION_MAIN otherwise getComponent() might 2096f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // return null for some shortcuts (for instance, for shortcuts to 2097f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // web pages.) 2098f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final Intent intent = info.intent; 2099f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final ComponentName name = intent.getComponent(); 2100f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && 210164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 210264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final int appCount = apps.size(); 2103aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung for (int k = 0; k < appCount; k++) { 210464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato ApplicationInfo app = apps.get(k); 210564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (app.componentName.equals(name)) { 210664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato info.setIcon(mIconCache.getIcon(info.intent)); 210764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato ((TextView)view).setCompoundDrawablesWithIntrinsicBounds(null, 210864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato new FastBitmapDrawable(info.getIcon(mIconCache)), 210964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato null, null); 211064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 211164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 2112f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 2113f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 2114f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 2115f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 2116f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 2117f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 211814f122bf847e50a3e7730ccbe57abc25d086a01bJoe Onorato void moveToDefaultScreen(boolean animate) { 2119c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka if (mIsSmall || mIsInUnshrinkAnimation) { 2120c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka mLauncher.showWorkspace(animate, (CellLayout)getChildAt(mDefaultPage)); 2121c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka } else if (animate) { 2122c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka snapToPage(mDefaultPage); 2123c45b16862918a0c6c253bba12032165b030565afJoe Onorato } else { 21240142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(mDefaultPage); 2125c45b16862918a0c6c253bba12032165b030565afJoe Onorato } 21260142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka getChildAt(mDefaultPage).requestFocus(); 212731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 212831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21298a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy void setIndicators(Drawable previous, Drawable next) { 21308a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy mPreviousIndicator = previous; 21318a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy mNextIndicator = next; 21320142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka previous.setLevel(mCurrentPage); 21330142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka next.setLevel(mCurrentPage); 21348a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy } 21358a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy 21360142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 21370142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public void syncPages() { 21380142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 213931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21400142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 21410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public void syncPageItems(int page) { 214231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 21430142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 214431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 2145