Workspace.java revision a985e598f6071f4caca15ba3cb6b2cd3e38b217d
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 19b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.animation.Animator; 20b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.animation.ObjectAnimator; 21af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport com.android.launcher.R; 22495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell 23df7c3a7853abd4dec460247370fe0b17b50866acPatrick Dubroyimport android.animation.PropertyValuesHolder; 24b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.animation.AnimatorSet; 25b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.animation.Animator.AnimatorListener; 268f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornimport android.app.WallpaperManager; 27629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetManager; 28629de3ef739883c0962423cc0c3a26299f162d3dRomain Guyimport android.appwidget.AppWidgetProviderInfo; 29495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.content.ComponentName; 3031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Context; 3131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.Intent; 32495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.content.pm.PackageManager; 335c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.content.pm.ProviderInfo; 347247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroyimport android.content.res.Resources; 3531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.content.res.TypedArray; 3631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Canvas; 37a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurkaimport android.graphics.Matrix; 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.graphics.Rect; 39f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.graphics.drawable.Drawable; 405c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guyimport android.net.Uri; 41956091ba7863bd72086275e61084864994dd6fa7Joe Onoratoimport android.os.IBinder; 42495f2892288504f4ab87e62957b3f71144dd73c2Adam Powellimport android.os.Parcelable; 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.util.AttributeSet; 44291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandlerimport android.util.Log; 4531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.MotionEvent; 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.View; 4731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectimport android.view.ViewGroup; 48f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.widget.TextView; 490e26059548e429e5d1c973bebe4c561bead2926fMichael Jurkaimport android.widget.Toast; 5031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 51af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport java.util.ArrayList; 52af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport java.util.HashSet; 53edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy 5431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/** 550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * The workspace is a wide area with a wallpaper and a finite number of pages. 560142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * Each page contains a number of icons, folders or widgets the user can 57aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * interact with. A workspace is meant to be used with a fixed width only. 5831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 590142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurkapublic class Workspace extends SmoothPagedView 60dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka implements DropTarget, DragSource, DragScroller, View.OnTouchListener { 61e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy @SuppressWarnings({"UnusedDeclaration"}) 623a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato private static final String TAG = "Launcher.Workspace"; 630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 64dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // This is how much the workspace shrinks when we enter all apps or 65dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // customization mode 66dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka private static final float SHRINK_FACTOR = 0.16f; 67a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 68a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // The maximum Y rotation to apply to the mini home screens 69a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private static final float MINI_PAGE_MAX_ROTATION = 25.0f; 70a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 71a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // These are extra scale factors to apply to the mini home screens 72a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // so as to achieve the desired transform 73a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private static final float EXTRA_SCALE_FACTOR_0 = 0.97f; 74a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private static final float EXTRA_SCALE_FACTOR_1 = 1.0f; 75a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private static final float EXTRA_SCALE_FACTOR_2 = 1.13f; 76a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 770142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private enum ShrinkPosition { SHRINK_TO_TOP, SHRINK_TO_MIDDLE, SHRINK_TO_BOTTOM }; 7831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 798f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private final WallpaperManager mWallpaperManager; 80aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 810142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private int mDefaultPage; 8231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka private boolean mWaitingToShrinkToBottom = false; 8431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 8631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * CellInfo for the cell that is currently being dragged 8731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 8831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private CellLayout.CellInfo mDragInfo; 89aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 9070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 9170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Target drop area calculated during last acceptDrop call. 9270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 9370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private int[] mTargetCell = null; 9431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 956569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy /** 966569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy * The CellLayout that is currently being dragged over 976569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy */ 986569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy private CellLayout mDragTargetLayout = null; 996569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 10031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private Launcher mLauncher; 1010589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato private IconCache mIconCache; 10200acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato private DragController mDragController; 103aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 10431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project private int[] mTempCell = new int[2]; 10570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private int[] mTempEstimate = new int[2]; 106a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka private float[] mTempDragCoordinates = new float[2]; 107a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka private float[] mTempDragBottomRightCoordinates = new float[2]; 10831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 109d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static final int DEFAULT_CELL_COUNT_X = 4; 110d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen private static final int DEFAULT_CELL_COUNT_Y = 4; 11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1128a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy private Drawable mPreviousIndicator; 1138a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy private Drawable mNextIndicator; 114aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // State variable that indicated whether the pages are small (ie when you're 116dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // in all apps or customize mode) 117dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka private boolean mIsSmall; 118b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase private AnimatorListener mUnshrinkAnimationListener; 119dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 120aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 12131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 12231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 12331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 12431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1250142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 12631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Workspace(Context context, AttributeSet attrs) { 12831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project this(context, attrs, 0); 12931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 13031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Used to inflate the Workspace from XML. 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param context The application's context. 1350142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param attrs The attributes set containing the Workspace's customization values. 13631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param defStyle Unused. 13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Workspace(Context context, AttributeSet attrs, int defStyle) { 13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super(context, attrs, defStyle); 1400142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mContentIsRefreshable = false; 1410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mFadeInAdjacentScreens = false; 14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1438f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn mWallpaperManager = WallpaperManager.getInstance(context); 144aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 145aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung TypedArray a = context.obtainStyledAttributes(attrs, 146aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung R.styleable.Workspace, defStyle, 0); 147d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int cellCountX = a.getInt(R.styleable.Workspace_cellCountX, DEFAULT_CELL_COUNT_X); 148d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int cellCountY = a.getInt(R.styleable.Workspace_cellCountY, DEFAULT_CELL_COUNT_Y); 1490142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1); 15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project a.recycle(); 15131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 152d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen LauncherModel.updateWorkspaceLayoutCells(cellCountX, cellCountY); 1530d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato setHapticFeedbackEnabled(false); 1540142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 15531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project initWorkspace(); 15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 15731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 15831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 15931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Initializes various states for this workspace. 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 1610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void initWorkspace() { 1620589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato Context context = getContext(); 1630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mCurrentPage = mDefaultPage; 1640142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 1650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato LauncherApplication app = (LauncherApplication)context.getApplicationContext(); 1660589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato mIconCache = app.getIconCache(); 16731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 168b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase mUnshrinkAnimationListener = new AnimatorListener() { 169b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase public void onAnimationStart(Animator animation) {} 170b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase public void onAnimationEnd(Animator animation) { 171dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka mIsSmall = false; 172dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 173b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase public void onAnimationCancel(Animator animation) {} 174b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase public void onAnimationRepeat(Animator animation) {} 175dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka }; 1760142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 1770142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mSnapVelocity = 600; 17831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 17931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 18131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int index, LayoutParams params) { 18231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 18331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 18431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, index, params); 18631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 18731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 18831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 18931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child) { 19031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 19131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 19231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 19331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child); 19431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 19531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 19631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 19731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int index) { 19831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 19931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 20031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 20131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, index); 20231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 20331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 20431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 20531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, int width, int height) { 20631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 20731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 20931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, width, height); 21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 21131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void addView(View child, LayoutParams params) { 21431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof CellLayout)) { 21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project throw new IllegalArgumentException("A Workspace can only have CellLayout children."); 21631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 21731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project super.addView(child, params); 21831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @return The open folder on the current screen, or null if there is none 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Folder getOpenFolder() { 2240142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout currentPage = (CellLayout) getChildAt(mCurrentPage); 2250142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int count = currentPage.getChildCount(); 22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 2270142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka View child = currentPage.getChildAt(i); 228aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (child instanceof Folder) { 229aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Folder folder = (Folder) child; 230aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder.getInfo().opened) 231aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung return folder; 23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ArrayList<Folder> getOpenFolders() { 238dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 239dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka ArrayList<Folder> folders = new ArrayList<Folder>(screenCount); 24031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 241dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int screen = 0; screen < screenCount; screen++) { 2420142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout currentPage = (CellLayout) getChildAt(screen); 2430142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int count = currentPage.getChildCount(); 24431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 2450142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka View child = currentPage.getChildAt(i); 246aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (child instanceof Folder) { 247aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Folder folder = (Folder) child; 248aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder.getInfo().opened) 249aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung folders.add(folder); 25031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 25131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return folders; 25631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2580142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka boolean isDefaultPageShowing() { 2590142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return mCurrentPage == mDefaultPage; 26031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 26131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 26231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Sets the current screen. 26431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 2650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * @param currentPage 26631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 2670142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 2680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka void setCurrentPage(int currentPage) { 2690142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.setCurrentPage(currentPage); 2700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka updateWallpaperOffset(mScrollX); 27131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 27231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the current screen. The position and dimension of 27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 27931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 28131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 28231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInCurrentScreen(View child, int x, int y, int spanX, int spanY) { 2840142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka addInScreen(child, mCurrentPage, x, y, spanX, spanY, false); 28531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 28831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the current screen. The position and dimension of 28931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 29031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 29131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 29231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 29331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 29631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param insert When true, the child is inserted at the beginning of the children list. 29731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInCurrentScreen(View child, int x, int y, int spanX, int spanY, boolean insert) { 2990142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka addInScreen(child, mCurrentPage, x, y, spanX, spanY, insert); 30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 30131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 30231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 30331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the specified screen. The position and dimension of 30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param screen The screen in which to add the child. 30831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 30931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 31031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 31131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 31231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 31331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInScreen(View child, int screen, int x, int y, int spanX, int spanY) { 31431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project addInScreen(child, screen, x, y, spanX, spanY, false); 31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 317aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung void addInFullScreen(View child, int screen) { 318aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung addInScreen(child, screen, 0, 0, -1, -1); 319aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 320aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 32131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project /** 32231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Adds the specified child in the specified screen. The position and dimension of 32331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * the child are defined by x, y, spanX and spanY. 32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param child The child to add in one of the workspace's screens. 32631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param screen The screen in which to add the child. 32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param x The X position of the child in the screen's grid. 32831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param y The Y position of the child in the screen's grid. 32931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanX The number of cells spanned horizontally by the child. 33031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param spanY The number of cells spanned vertically by the child. 33131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * @param insert When true, the child is inserted at the beginning of the children list. 33231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */ 33331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void addInScreen(View child, int screen, int x, int y, int spanX, int spanY, boolean insert) { 33431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (screen < 0 || screen >= getChildCount()) { 335291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler Log.e(TAG, "The screen must be >= 0 and < " + getChildCount() 336291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler + " (was " + screen + "); skipping child"); 337291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler return; 33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 33931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 34031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout group = (CellLayout) getChildAt(screen); 34131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 34231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (lp == null) { 34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp = new CellLayout.LayoutParams(x, y, spanX, spanY); 34431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 34531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellX = x; 34631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellY = y; 34731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellHSpan = spanX; 34831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project lp.cellVSpan = spanY; 34931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 350aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 3516569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // Get the canonical child id to uniquely represent this view in this screen 352d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int childId = LauncherModel.getCellLayoutChildId(child.getId(), screen, x, y, spanX, spanY); 353aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (!group.addViewToCellLayout(child, insert ? 0 : -1, childId, lp)) { 354aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // TODO: This branch occurs when the workspace is adding views 355aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // outside of the defined grid 3566569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // maybe we should be deleting these items from the LauncherModel? 357aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung Log.w(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout"); 358aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 359aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 36031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!(child instanceof Folder)) { 3610d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato child.setHapticFeedbackEnabled(false); 36231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project child.setOnLongClickListener(mLongClickListener); 36331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 36400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (child instanceof DropTarget) { 365aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mDragController.addDropTarget((DropTarget) child); 36600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 36731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 36831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 369a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout.CellInfo updateOccupiedCellsForCurrentScreen(boolean[] occupied) { 3700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout group = (CellLayout) getChildAt(mCurrentPage); 37131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (group != null) { 372c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka return group.updateOccupiedCells(occupied, null); 37331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 37431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 37531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 37631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 377dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka public boolean onTouch(View v, MotionEvent event) { 378dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // this is an intercepted event being forwarded from a cell layout 379dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka if (mIsSmall) { 3802b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy mLauncher.onWorkspaceClick((CellLayout) v); 38196226223d9849842bb2a67af051acbae9e0677d5Michael Jurka return true; 382dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 383dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka return false; 3840e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka } 3850e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka 3860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void pageBeginMoving() { 3870142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mNextPage != INVALID_PAGE) { 3880142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // we're snapping to a particular screen 3890142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka enableChildrenCache(mCurrentPage, mNextPage); 3900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 3910142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // this is when user is actively dragging a particular screen, they might 3920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // swipe it either left or right (but we won't advance by more than one screen) 3930142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka enableChildrenCache(mCurrentPage - 1, mCurrentPage + 1); 39431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 39531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 39631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 3970142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void pageEndMoving() { 3980142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka clearChildrenCache(); 3990142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4000142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4010142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 4020142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void notifyPageSwitchListener() { 4030142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.notifyPageSwitchListener(); 4040142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4050142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mPreviousIndicator != null) { 4060142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // if we know the next page, we show the indication for it right away; it looks 4070142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // weird if the indicators are lagging 4080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int page = mNextPage; 4090142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (page == INVALID_PAGE) { 4100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka page = mCurrentPage; 4110142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mPreviousIndicator.setLevel(page); 4130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mNextIndicator.setLevel(page); 4140142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 4160142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka }; 4170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4188f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn private void updateWallpaperOffset() { 419798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy updateWallpaperOffset(getChildAt(getChildCount() - 1).getRight() - (mRight - mLeft)); 420798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy } 421798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy 422798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy private void updateWallpaperOffset(int scrollRange) { 42386f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung final boolean isStaticWallpaper = (mWallpaperManager != null) && 42486f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung (mWallpaperManager.getWallpaperInfo() == null); 42586f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung if (LauncherApplication.isScreenXLarge() && !isStaticWallpaper) { 42686f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung IBinder token = getWindowToken(); 42786f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung if (token != null) { 42886f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0 ); 42986f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung mWallpaperManager.setWallpaperOffsets(getWindowToken(), 43086f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung Math.max(0.f, Math.min(mScrollX/(float)scrollRange, 1.f)), 0); 43186f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung } 432956091ba7863bd72086275e61084864994dd6fa7Joe Onorato } 4338f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn } 434aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 43500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato protected void onAttachedToWindow() { 43600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato super.onAttachedToWindow(); 437956091ba7863bd72086275e61084864994dd6fa7Joe Onorato computeScroll(); 43800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.setWindowToken(getWindowToken()); 43900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 44000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato 44131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 44231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 4430142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.onLayout(changed, left, top, right, bottom); 444aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 44579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // if shrinkToBottom() is called on initialization, it has to be deferred 44679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // until after the first call to onLayout so that it has the correct width 44779212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka if (mWaitingToShrinkToBottom) { 44879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka shrinkToBottom(false); 44979212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka mWaitingToShrinkToBottom = false; 45079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 45179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka 452aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (LauncherApplication.isInPlaceRotationEnabled()) { 453aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // When the device is rotated, the scroll position of the current screen 454aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // needs to be refreshed 4550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(getCurrentPage()); 456aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung } 45731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 45831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 45931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 4600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void dispatchDraw(Canvas canvas) { 4610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (mIsSmall) { 4620142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // Draw all the workspaces if we're small 4630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageCount = getChildCount(); 4640142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final long drawingTime = getDrawingTime(); 4650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka for (int i = 0; i < pageCount; i++) { 4660142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final View page = (View) getChildAt(i); 4670142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 4680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (page.getAlpha() != 1.0f) { 4690142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka page.setAlpha(1.0f); 4700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4710142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka drawChild(canvas, page, drawingTime); 4720142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 4730142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 4740142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.dispatchDraw(canvas); 47531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 47631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 47731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 47831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 47931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { 480678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato if (!mLauncher.isAllAppsVisible()) { 48131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Folder openFolder = getOpenFolder(); 48231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (openFolder != null) { 48331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return openFolder.requestFocus(direction, previouslyFocusedRect); 48431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 4850142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return super.onRequestFocusInDescendants(direction, previouslyFocusedRect); 48631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 48731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 48831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return false; 48931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 49031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 49131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 492c2e24c0a37ddeab930f731c062705d435e477f75Romain Guy public void addFocusables(ArrayList<View> views, int direction, int focusableMode) { 493678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato if (!mLauncher.isAllAppsVisible()) { 49431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final Folder openFolder = getOpenFolder(); 4950142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (openFolder != null) { 49631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project openFolder.addFocusables(views, direction); 4970142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else { 4980142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.addFocusables(views, direction, focusableMode); 49931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 50031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 50131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 50231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 50331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 5047bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato public boolean dispatchTouchEvent(MotionEvent ev) { 5057bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato if (ev.getAction() == MotionEvent.ACTION_DOWN) { 50654dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka // (In XLarge mode, the workspace is shrunken below all apps, and responds to taps 50754dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka // ie when you click on a mini-screen, it zooms back to that screen) 5086b4adbc0558fcebbd44998bd00dcd334ddbee32dJoe Onorato if (!LauncherApplication.isScreenXLarge() && mLauncher.isAllAppsVisible()) { 5097bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato return false; 5107bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 5117bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 5127bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato return super.dispatchTouchEvent(ev); 5137bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato } 5147bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato 5150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka void enableChildrenCache(int fromPage, int toPage) { 5160142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (fromPage > toPage) { 5170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int temp = fromPage; 5180142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka fromPage = toPage; 5190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka toPage = temp; 5203a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron } 521aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 522dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 523fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell 5240142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka fromPage = Math.max(fromPage, 0); 5250142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka toPage = Math.min(toPage, screenCount - 1); 526fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell 5270142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka for (int i = fromPage; i <= toPage; i++) { 52831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 52931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawnWithCacheEnabled(true); 53031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawingCacheEnabled(true); 53131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 53231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 53331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 53431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void clearChildrenCache() { 535dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 536dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 53731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 53831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.setChildrenDrawnWithCacheEnabled(false); 53931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 54131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 54231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project @Override 54331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public boolean onTouchEvent(MotionEvent ev) { 5442bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (mLauncher.isAllAppsVisible()) { 5452bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato // Cancel any scrolling that is in progress. 5462bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato if (!mScroller.isFinished()) { 5472bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato mScroller.abortAnimation(); 5482bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato } 5490142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka snapToPage(mCurrentPage); 5507c312c15e33b6cffbda707429e88ade498fc9f5eJoe Onorato return false; // We don't want the events. Let them fall through to the all apps view. 55131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 55231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 5530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka return super.onTouchEvent(ev); 55431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 555aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 55601f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka public boolean isSmall() { 55701f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka return mIsSmall; 55801f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka } 55901f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka 5606b509c1fd62a39916bb957eac07917161f549206Patrick Dubroy void shrinkToTop(boolean animated) { 5610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_TOP, animated); 56201f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka } 56301f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka 56401f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka void shrinkToMiddle() { 5650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_MIDDLE, true); 566213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 567213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 568213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka void shrinkToBottom() { 56979212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka shrinkToBottom(true); 57079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 57179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka 57279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka void shrinkToBottom(boolean animated) { 57379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka if (mFirstLayout) { 57479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // (mFirstLayout == "first layout has not happened yet") 57579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // if we get a call to shrink() as part of our initialization (for example, if 57679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // Launcher is started in All Apps mode) then we need to wait for a layout call 57779212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka // to get our width so we can layout the mini-screen views correctly 57879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka mWaitingToShrinkToBottom = true; 57979212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } else { 5800142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka shrink(ShrinkPosition.SHRINK_TO_BOTTOM, animated); 58179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 582213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 583213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 584a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen private float getYScaleForScreen(int screen) { 585a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen int x = Math.abs(screen - 2); 586a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 587a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // TODO: This should be generalized for use with arbitrary rotation angles. 588a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen switch(x) { 589a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 0: return EXTRA_SCALE_FACTOR_0; 590a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 1: return EXTRA_SCALE_FACTOR_1; 591a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen case 2: return EXTRA_SCALE_FACTOR_2; 592a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen } 593a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen return 1.0f; 594a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen } 595a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 596dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // we use this to shrink the workspace for the all apps view and the customize view 5970142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private void shrink(ShrinkPosition shrinkPosition, boolean animated) { 598dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka mIsSmall = true; 5997247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final Resources res = getResources(); 600dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenWidth = getWidth(); 601213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka final int screenHeight = getHeight(); 6020142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 6030142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka // Making the assumption that all pages have the same width as the 0th 6040142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageWidth = getChildAt(0).getMeasuredWidth(); 6050142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int pageHeight = getChildAt(0).getMeasuredHeight(); 6060142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 6070142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int scaledPageWidth = (int) (SHRINK_FACTOR * pageWidth); 6080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka final int scaledPageHeight = (int) (SHRINK_FACTOR * pageHeight); 609a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen final float extraScaledSpacing = res.getDimension(R.dimen.smallScreenExtraSpacing); 610dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 611dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 612a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float totalWidth = screenCount * scaledPageWidth + (screenCount - 1) * extraScaledSpacing; 613213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka 614213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka float newY = getResources().getDimension(R.dimen.smallScreenVerticalMargin); 6150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (shrinkPosition == ShrinkPosition.SHRINK_TO_BOTTOM) { 6160142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka newY = screenHeight - newY - scaledPageHeight; 6170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_MIDDLE) { 6180142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka newY = screenHeight / 2 - scaledPageHeight / 2; 619213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka } 620dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 621dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // We animate all the screens to the centered position in workspace 622dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // At the same time, the screens become greyed/dimmed 623dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 624dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // newX is initialized to the left-most position of the centered screens 6250142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka float newX = mScroller.getFinalX() + screenWidth / 2 - totalWidth / 2; 626a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 627a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // We are going to scale about the center of the view, so we need to adjust the positions 628a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen // of the views accordingly 629a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newX -= (pageWidth - scaledPageWidth) / 2.0f; 630a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newY -= (pageHeight - scaledPageHeight) / 2.0f; 631dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 632dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka CellLayout cl = (CellLayout) getChildAt(i); 633a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 634a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float rotation = (-i + 2) * MINI_PAGE_MAX_ROTATION / 2.0f; 635a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float rotationScaleX = (float) (1.0f / Math.cos(Math.PI * rotation / 180.0f)); 636a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen float rotationScaleY = getYScaleForScreen(i); 637a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 63879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka if (animated) { 6397247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final int duration = res.getInteger(R.integer.config_workspaceShrinkTime); 640b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase new ObjectAnimator(duration, cl, 641df7c3a7853abd4dec460247370fe0b17b50866acPatrick Dubroy new PropertyValuesHolder("x", newX), 642df7c3a7853abd4dec460247370fe0b17b50866acPatrick Dubroy new PropertyValuesHolder("y", newY), 643a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen new PropertyValuesHolder("scaleX", SHRINK_FACTOR * rotationScaleX), 644a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen new PropertyValuesHolder("scaleY", SHRINK_FACTOR * rotationScaleY), 645a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen new PropertyValuesHolder("dimmedBitmapAlpha", 1.0f), 646a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen new PropertyValuesHolder("rotationY", rotation)).start(); 64779212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } else { 64879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setX((int)newX); 64979212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setY((int)newY); 65079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setScaleX(SHRINK_FACTOR); 65179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setScaleY(SHRINK_FACTOR); 65279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka cl.setDimmedBitmapAlpha(1.0f); 653a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen cl.setRotationY(rotation); 65479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka } 655dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // increment newX for the next screen 656a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen newX += scaledPageWidth + extraScaledSpacing; 657dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka cl.setOnInterceptTouchListener(this); 658dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 659dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka setChildrenDrawnWithCacheEnabled(true); 660dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 661dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 662dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // We call this when we trigger an unshrink by clicking on the CellLayout cl 6632b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy public void unshrink(CellLayout clThatWasClicked) { 6640142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int newCurrentPage = mCurrentPage; 6654cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka final int screenCount = getChildCount(); 6664cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka for (int i = 0; i < screenCount; i++) { 6674cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka if (getChildAt(i) == clThatWasClicked) { 6680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka newCurrentPage = i; 6694cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 6704cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 6710142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka unshrink(newCurrentPage); 6724cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 6734cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 6740142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private void unshrink(int newCurrentPage) { 675b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka if (mIsSmall) { 6760142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int delta = (newCurrentPage - mCurrentPage)*getWidth(); 6774cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 678b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka final int screenCount = getChildCount(); 679b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka for (int i = 0; i < screenCount; i++) { 680b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka CellLayout cl = (CellLayout) getChildAt(i); 681b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka cl.setX(cl.getX() + delta); 682b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 6830142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka snapToPage(newCurrentPage); 684b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka unshrink(); 6850142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 6860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(newCurrentPage); 687b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 688dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 689dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 6904cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka void unshrink() { 6914cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka unshrink(true); 6924cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 6934cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 6944cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka void unshrink(boolean animated) { 695b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka if (mIsSmall) { 696b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase AnimatorSet s = new AnimatorSet(); 697b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka final int screenCount = getChildCount(); 6984cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka 6994cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka final int duration = getResources().getInteger(R.integer.config_workspaceUnshrinkTime); 700b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka for (int i = 0; i < screenCount; i++) { 7017247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy final CellLayout cl = (CellLayout)getChildAt(i); 7024cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka if (animated) { 7034cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka s.playTogether( 704b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase new ObjectAnimator<Float>(duration, cl, "translationX", 0.0f), 705b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase new ObjectAnimator<Float>(duration, cl, "translationY", 0.0f), 706b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase new ObjectAnimator<Float>(duration, cl, "scaleX", 1.0f), 707b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase new ObjectAnimator<Float>(duration, cl, "scaleY", 1.0f), 708a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen new ObjectAnimator<Float>(duration, cl, "dimmedBitmapAlpha", 0.0f), 709a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen new ObjectAnimator<Float>(duration, cl, "rotationY", 0.0f)); 7104cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } else { 7114cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setTranslationX(0.0f); 7124cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setTranslationY(0.0f); 7134cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setScaleX(1.0f); 7144cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setScaleY(1.0f); 7154cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka cl.setDimmedBitmapAlpha(0.0f); 716a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen cl.setRotationY(0.0f); 7174cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 718b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka } 719b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka s.addListener(mUnshrinkAnimationListener); 720b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka s.start(); 721dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 722dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka } 723dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka 72431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void startDrag(CellLayout.CellInfo cellInfo) { 72531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = cellInfo.cell; 726aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 72731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Make sure the drag was started by a long press as opposed to a long click. 7287984c9496bcaeca23ee7fdecc4d4f1bb2467e0f2Bjorn Bringert if (!child.isInTouchMode()) { 72931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 73031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 731aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 73231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = cellInfo; 7330142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka mDragInfo.screen = mCurrentPage; 734aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 7350142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka CellLayout current = ((CellLayout) getChildAt(mCurrentPage)); 73631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 73731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project current.onDragChild(child); 73800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.startDrag(child, this, child.getTag(), DragController.DRAG_ACTION_MOVE); 73931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project invalidate(); 74031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 74131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7420589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato void addApplicationShortcut(ShortcutInfo info, CellLayout.CellInfo cellInfo) { 74331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project addApplicationShortcut(info, cellInfo, false); 74431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 74531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 7460589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato void addApplicationShortcut(ShortcutInfo info, CellLayout.CellInfo cellInfo, 74731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project boolean insertAtFirst) { 74831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(cellInfo.screen); 74931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final int[] result = new int[2]; 75031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 75131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project layout.cellToPoint(cellInfo.cellX, cellInfo.cellY, result); 75231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project onDropExternal(result[0], result[1], info, layout, insertAtFirst); 75331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 75431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 75500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset, 75600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato DragView dragView, Object dragInfo) { 757a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout cellLayout = getCurrentDropLayout(); 758a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka int originX = x - xOffset; 759a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka int originY = y - yOffset; 760a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (mIsSmall) { 761a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // find out which target layout is over 762a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final float[] localXY = mTempDragCoordinates; 763a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localXY[0] = originX; 764a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localXY[1] = originY; 765a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final float[] localBottomRightXY = mTempDragBottomRightCoordinates; 766a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // we need to subtract left/top here because DragController already adds 767a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // dragRegionLeft/Top to xOffset and yOffset 768a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localBottomRightXY[0] = originX + dragView.getDragRegionWidth(); 769a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localBottomRightXY[1] = originY + dragView.getDragRegionHeight(); 7700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka cellLayout = findMatchingPageForDragOver(localXY, localBottomRightXY); 771a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (cellLayout == null) { 772a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // cancel the drag if we're not over a mini-screen at time of drop 773a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // TODO: maybe add a nice fade here? 774a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka return; 775a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 776a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // localXY will be transformed into the local screen's coordinate space; save that info 777a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka originX = (int)localXY[0]; 778a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka originY = (int)localXY[1]; 779a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 78031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (source != this) { 781a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka onDropExternal(originX, originY, dragInfo, cellLayout); 78231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 78331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Move internally 78431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDragInfo != null) { 78531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final View cell = mDragInfo.cell; 7860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int index = mScroller.isFinished() ? mCurrentPage : mNextPage; 78752d9cb32608e7c3d065b4fb8e97269e238f1683eRomain Guy if (index != mDragInfo.screen) { 78831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen); 78931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project originalCellLayout.removeView(cell); 790aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung addInScreen(cell, index, mDragInfo.cellX, mDragInfo.cellY, 791aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mDragInfo.spanX, mDragInfo.spanY); 79231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 793a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 794a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka mTargetCell = estimateDropCell(originX, originY, 795aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout, 796aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mTargetCell); 797aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung cellLayout.onDropChild(cell); 79831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 799aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // update the item's position after drop 80084f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy final ItemInfo info = (ItemInfo) cell.getTag(); 801aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell 802aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung .getLayoutParams(); 803aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung lp.cellX = mTargetCell[0]; 804aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung lp.cellY = mTargetCell[1]; 805aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 80631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project LauncherModel.moveItemInDatabase(mLauncher, info, 807aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung LauncherSettings.Favorites.CONTAINER_DESKTOP, index, 808aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung lp.cellX, lp.cellY); 80931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 81031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 81131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 81231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 813aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void onDragEnter(DragSource source, int x, int y, int xOffset, 814aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int yOffset, DragView dragView, Object dragInfo) { 81531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 81631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 817440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset, 8186569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy DragView dragView, Object dragInfo) { 8196569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 820440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // We may need to delegate the drag to a child view. If a 1x1 item 821440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // would land in a cell occupied by a DragTarget (e.g. a Folder), 822440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // then drag events should be handled by that child. 823440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 8246569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy ItemInfo item = (ItemInfo)dragInfo; 825440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy CellLayout currentLayout = getCurrentDropLayout(); 826440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 827440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy int dragPointX, dragPointY; 828440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (item.spanX == 1 && item.spanY == 1) { 829440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // For a 1x1, calculate the drop cell exactly as in onDragOver 830440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointX = x - xOffset; 831440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointY = y - yOffset; 832440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } else { 833440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // Otherwise, use the exact drag coordinates 834440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointX = x; 835440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy dragPointY = y; 836440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 837440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 838440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // If we are dragging over a cell that contains a DropTarget that will 839440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy // accept the drop, delegate to that DropTarget. 840440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy final int[] cellXY = mTempCell; 841440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY); 842440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy View child = currentLayout.getChildAt(cellXY[0], cellXY[1]); 843440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (child instanceof DropTarget) { 844440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy DropTarget target = (DropTarget)child; 845440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy if (target.acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)) { 846440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy return target; 847440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 848440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 849440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy return null; 850440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy } 8516569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 852a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // xy = upper left corner of item being dragged 853a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // bottomRightXy = lower right corner of item being dragged 854a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // This method will see which mini-screen is most overlapped by the item being dragged, and 855a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // return it. It will also transform the parameters xy and bottomRightXy into the local 856a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // coordinate space of the returned screen 8570142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka private CellLayout findMatchingPageForDragOver(float[] xy, float[] bottomRightXy) { 858a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float x = xy[0]; 859a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float y = xy[1]; 860a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float right = bottomRightXy[0]; 861a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float bottom = bottomRightXy[1]; 862a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 863a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float bestX = 0; 864a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float bestY = 0; 865a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float bestRight = 0; 866a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float bestBottom = 0; 867a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 868a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka Matrix inverseMatrix = new Matrix(); 869a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 870a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // We loop through all the screens (ie CellLayouts) and see which one overlaps the most 871a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // with the item being dragged. 872a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final int screenCount = getChildCount(); 873a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout bestMatchingScreen = null; 874a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float bestOverlapSoFar = 0; 875a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka for (int i = 0; i < screenCount; i++) { 876a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout cl = (CellLayout)getChildAt(i); 877a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // Transform the coordinates of the item being dragged to the CellLayout's coordinates 878a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float left = cl.getLeft(); 879a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float top = cl.getTop(); 880a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka xy[0] = x + mScrollX - left; 881a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka xy[1] = y + mScrollY - top; 882a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka cl.getMatrix().invert(inverseMatrix); 883a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 884a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bottomRightXy[0] = right + mScrollX - left; 885a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bottomRightXy[1] = bottom + mScrollY - top; 886a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 887a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka inverseMatrix.mapPoints(xy); 888a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka inverseMatrix.mapPoints(bottomRightXy); 889a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 890a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float dragRegionX = xy[0]; 891a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float dragRegionY = xy[1]; 892a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float dragRegionRight = bottomRightXy[0]; 893a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float dragRegionBottom = bottomRightXy[1]; 894a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 895a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // Find the overlapping region 896a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float overlapLeft = Math.max(0f, dragRegionX); 897a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float overlapTop = Math.max(0f, dragRegionY); 898a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float overlapBottom = Math.min(cl.getHeight(), dragRegionBottom); 899a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float overlapRight = Math.min(cl.getWidth(), dragRegionRight); 900a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 901a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (overlapRight >= 0 && overlapLeft <= cl.getWidth() && 902a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka overlapTop >= 0 && overlapBottom <= cl.getHeight()) { 903a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // Calculate the size of the overlapping region 904a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka float overlap = (overlapRight - overlapLeft) * (overlapBottom - overlapTop); 905a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (overlap > bestOverlapSoFar) { 906a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestOverlapSoFar = overlap; 907a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestMatchingScreen = cl; 908a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestX = xy[0]; 909a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestY = xy[1]; 910a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestRight = bottomRightXy[0]; 911a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bestBottom = bottomRightXy[1]; 912a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 913a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 914a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 915a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (bestMatchingScreen != null && bestMatchingScreen != mDragTargetLayout) { 916a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (mDragTargetLayout != null) { 917a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka mDragTargetLayout.onDragComplete(); 918a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 919a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka mDragTargetLayout = bestMatchingScreen; 920a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 921a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka xy[0] = bestX; 922a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka xy[1] = bestY; 923a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bottomRightXy[0] = bestRight; 924a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka bottomRightXy[1] = bestBottom; 925a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka return bestMatchingScreen; 926a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 927a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 928440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, 929440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy DragView dragView, Object dragInfo) { 930440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy 931976ebec9e31643d3513f9f0de2b433d9aa186ce9Patrick Dubroy final ItemInfo item = (ItemInfo)dragInfo; 932a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka CellLayout currentLayout = getCurrentDropLayout(); 9336569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 9346569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (dragInfo instanceof LauncherAppWidgetInfo) { 9356569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo)dragInfo; 9366569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 9376569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (widgetInfo.spanX == -1) { 9386569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // Calculate the grid spans needed to fit this widget 9398f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy int[] spans = currentLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, null); 9406569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy item.spanX = spans[0]; 9416569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy item.spanY = spans[1]; 9426569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 9436569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 944a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka int originX = x - xOffset; 945a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka int originY = y - yOffset; 946a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (mIsSmall) { 947a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // find out which mini screen the dragged item is over 948a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final float[] localXY = mTempDragCoordinates; 949a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localXY[0] = originX; 950a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localXY[1] = originY; 951a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final float[] localBottomRightXY = mTempDragBottomRightCoordinates; 952a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 953a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localBottomRightXY[0] = originX + dragView.getDragRegionWidth(); 954a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka localBottomRightXY[1] = originY + dragView.getDragRegionHeight(); 9550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka currentLayout = findMatchingPageForDragOver(localXY, localBottomRightXY); 956a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (currentLayout != null) { 957a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka currentLayout.setHover(true); 958a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 959a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 960a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka originX = (int)localXY[0]; 961a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka originY = (int)localXY[1]; 962a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 963a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 964a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (source != this) { 965a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // This is a hack to fix the point used to determine which cell an icon from the all 966a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // apps screen is over 967a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (item != null && item.spanX == 1 && currentLayout != null) { 968a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka int dragRegionLeft = (dragView.getWidth() - currentLayout.getCellWidth()) / 2; 969a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 970a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka originX += dragRegionLeft - dragView.getDragRegionLeft(); 971a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if (dragView.getDragRegionWidth() != currentLayout.getCellWidth()) { 972a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka dragView.setDragRegion(dragView.getDragRegionLeft(), dragView.getDragRegionTop(), 973a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka currentLayout.getCellWidth(), dragView.getDragRegionHeight()); 974a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 975a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 976a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka } 9776569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (currentLayout != mDragTargetLayout) { 9786569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (mDragTargetLayout != null) { 9796569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy mDragTargetLayout.onDragComplete(); 9806569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 9816569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy mDragTargetLayout = currentLayout; 9826569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 9836569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 984a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // only visualize the drop locations for moving icons within the home screen on tablet 985a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka // on phone, we also visualize icons dragged in from All Apps 986a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka if ((!LauncherApplication.isScreenXLarge() || source == this) 987a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka && mDragTargetLayout != null) { 988a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka final View child = (mDragInfo == null) ? null : mDragInfo.cell; 989a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka mDragTargetLayout.visualizeDropLocation( 990a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka child, originX, originY, item.spanX, item.spanY); 991976ebec9e31643d3513f9f0de2b433d9aa186ce9Patrick Dubroy } 99231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 99331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 994aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung public void onDragExit(DragSource source, int x, int y, int xOffset, 995aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int yOffset, DragView dragView, Object dragInfo) { 9966569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (mDragTargetLayout != null) { 9976569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy mDragTargetLayout.onDragComplete(); 9986569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy mDragTargetLayout = null; 9996569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 100031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 100131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1002aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung private void onDropExternal(int x, int y, Object dragInfo, 1003aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung CellLayout cellLayout) { 100431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project onDropExternal(x, y, dragInfo, cellLayout, false); 100531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1006aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 10072b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy /** 10082b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * Add the item specified by dragInfo to the given layout. 10092b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * This is basically the equivalent of onDropExternal, except it's not initiated 10102b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * by drag and drop. 10112b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy * @return true if successful 10122b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy */ 10132b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy public boolean addExternalItemToScreen(Object dragInfo, View layout) { 10142b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy CellLayout cl = (CellLayout) layout; 10152b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy ItemInfo info = (ItemInfo) dragInfo; 10162b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy 10172b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy final CellLayout.CellInfo cellInfo = cl.updateOccupiedCells(null, null); 10182b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy if (cellInfo.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) { 10192b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy onDropExternal(0, 0, dragInfo, cl, false); 10202b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy return true; 10212b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy } 10222b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy return false; 10232b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy } 10242b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy 1025aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung private void onDropExternal(int x, int y, Object dragInfo, 1026aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung CellLayout cellLayout, boolean insertAtFirst) { 102731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Drag from somewhere else 102831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project ItemInfo info = (ItemInfo) dragInfo; 102931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1030af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka View view = null; 103131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 103231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project switch (info.itemType) { 103331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: 103431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: 1035e48e7c1a62e6a367803dca62c8fce9de57121b0fJoe Onorato if (info.container == NO_ID && info instanceof ApplicationInfo) { 103631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Came from all apps -- make a copy 1037aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung info = new ShortcutInfo((ApplicationInfo) info); 103831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1039aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung view = mLauncher.createShortcut(R.layout.application, cellLayout, 1040aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung (ShortcutInfo) info); 104131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 104231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER: 104331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, 10440142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka (ViewGroup) getChildAt(mCurrentPage), 1045aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung ((UserFolderInfo) info)); 104631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project break; 1047af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: 1048af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka cellLayout.setTagToCellInfoForPoint(x, y); 1049a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka int[] position = new int[2]; 1050a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka position[0] = x; 1051a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka position[1] = y; 1052a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka mLauncher.addAppWidgetFromDrop(((LauncherAppWidgetInfo)dragInfo).providerName, 1053a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka cellLayout.getTag(), position); 1054af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka break; 105531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project default: 1056aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung throw new IllegalStateException("Unknown item type: " 1057aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung + info.itemType); 105831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 105931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 10606569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // If the view is null, it has already been added. 10616569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (view == null) { 10626569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy cellLayout.onDragComplete(); 10636569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } else { 10646569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy mTargetCell = estimateDropCell(x, y, 1, 1, view, cellLayout, mTargetCell); 1065aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung addInScreen(view, indexOfChild(cellLayout), mTargetCell[0], 1066aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung mTargetCell[1], info.spanX, info.spanY, insertAtFirst); 1067aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung cellLayout.onDropChild(view); 10686569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams(); 106931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1070af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka LauncherModel.addOrMoveItemInDatabase(mLauncher, info, 10710142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka LauncherSettings.Favorites.CONTAINER_DESKTOP, mCurrentPage, 1072aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung lp.cellX, lp.cellY); 1073af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka } 107431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1075aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 107670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 107770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Return the current {@link CellLayout}, correctly picking the destination 107870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * screen while a scroll is in progress. 107970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 108070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey private CellLayout getCurrentDropLayout() { 10810142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka int index = mScroller.isFinished() ? mCurrentPage : mNextPage; 108270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey return (CellLayout) getChildAt(index); 108370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 108431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 108570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 108670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * {@inheritDoc} 108770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 108870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey public boolean acceptDrop(DragSource source, int x, int y, 108900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int xOffset, int yOffset, DragView dragView, Object dragInfo) { 10904c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy final CellLayout layout = getCurrentDropLayout(); 1091c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final CellLayout.CellInfo dragCellInfo = mDragInfo; 1092c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final int spanX = dragCellInfo == null ? 1 : dragCellInfo.spanX; 1093c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final int spanY = dragCellInfo == null ? 1 : dragCellInfo.spanY; 10944c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy 1095c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final View ignoreView = dragCellInfo == null ? null : dragCellInfo.cell; 1096c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final CellLayout.CellInfo cellInfo = layout.updateOccupiedCells(null, ignoreView); 10974c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy 1098c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka if (cellInfo.findCellForSpan(mTempEstimate, spanX, spanY)) { 10990e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka return true; 11000e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka } else { 11010e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka Toast.makeText(getContext(), getContext().getString(R.string.out_of_space), Toast.LENGTH_SHORT).show(); 11020e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka return false; 11030e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka } 110470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 1105aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 110670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 110770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * {@inheritDoc} 110870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 110970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey public Rect estimateDropLocation(DragSource source, int x, int y, 111000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato int xOffset, int yOffset, DragView dragView, Object dragInfo, Rect recycle) { 111170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey final CellLayout layout = getCurrentDropLayout(); 1112aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 111331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout.CellInfo cellInfo = mDragInfo; 111470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey final int spanX = cellInfo == null ? 1 : cellInfo.spanX; 111570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey final int spanY = cellInfo == null ? 1 : cellInfo.spanY; 111670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey final View ignoreView = cellInfo == null ? null : cellInfo.cell; 1117aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 111870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey final Rect location = recycle != null ? recycle : new Rect(); 1119aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 112070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey // Find drop cell and convert into rectangle 1121aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung int[] dropCell = estimateDropCell(x - xOffset, y - yOffset, spanX, 1122aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung spanY, ignoreView, layout, mTempCell); 1123aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 112470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (dropCell == null) { 112570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey return null; 112670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 1127aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 112870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey layout.cellToPoint(dropCell[0], dropCell[1], mTempEstimate); 112970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey location.left = mTempEstimate[0]; 113070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey location.top = mTempEstimate[1]; 1131aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 113270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey layout.cellToPoint(dropCell[0] + spanX, dropCell[1] + spanY, mTempEstimate); 113370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey location.right = mTempEstimate[0]; 113470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey location.bottom = mTempEstimate[1]; 1135aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 113670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey return location; 113731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 113831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 113970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey /** 114070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey * Calculate the nearest cell where the given object would be dropped. 114170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey */ 1142263e019baafb3b6cbcfdef9c81d74a4bea769180Romain Guy private int[] estimateDropCell(int pixelX, int pixelY, 114370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) { 11446569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 11456569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy final int[] cellXY = mTempCell; 11466569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy layout.estimateDropCell(pixelX, pixelY, spanX, spanY, cellXY); 11476569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy layout.cellToPoint(cellXY[0], cellXY[1], mTempEstimate); 11486569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1149c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka final CellLayout.CellInfo cellInfo = layout.updateOccupiedCells(null, ignoreView); 115070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey // Find the best target drop location 1151c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka return layout.findNearestVacantArea(mTempEstimate[0], mTempEstimate[1], spanX, spanY, cellInfo, recycle); 115270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey } 1153aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 11548f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy /** 11558f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy * Estimate the size that a child with the given dimensions will take in the current screen. 11568f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy */ 11578f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy void estimateChildSize(int minWidth, int minHeight, int[] result) { 11580142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka ((CellLayout)getChildAt(mCurrentPage)).estimateChildSize(minWidth, minHeight, result); 11598f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy } 11608f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy 116131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project void setLauncher(Launcher launcher) { 116231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mLauncher = launcher; 116331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 116431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 116500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato public void setDragController(DragController dragController) { 116600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController = dragController; 116731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 116831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 116931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void onDropCompleted(View target, boolean success) { 1170aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (success) { 117131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (target != this && mDragInfo != null) { 117231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); 117331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project cellLayout.removeView(mDragInfo.cell); 117400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato if (mDragInfo.cell instanceof DropTarget) { 117500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato mDragController.removeDropTarget((DropTarget)mDragInfo.cell); 117600acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato } 1177aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // final Object tag = mDragInfo.cell.getTag(); 117831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 117931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } else { 118031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (mDragInfo != null) { 118131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen); 118231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project cellLayout.onDropAborted(mDragInfo.cell); 118331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 118431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 118531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 118631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project mDragInfo = null; 118731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 118831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 11890142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 11900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka protected void onRestoreInstanceState(Parcelable state) { 11910142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.onRestoreInstanceState(state); 11920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka Launcher.setScreen(mCurrentPage); 11930142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 11940142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 11950142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 119631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void scrollLeft() { 11977f0f4f3c35fe0b6a94504ec39ac127fa935282efMichael Jurka if (!mIsSmall) { 11980142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.scrollLeft(); 119931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 120031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 120131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 12020142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 120331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public void scrollRight() { 12047f0f4f3c35fe0b6a94504ec39ac127fa935282efMichael Jurka if (!mIsSmall) { 12050142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka super.scrollRight(); 120631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 120731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1208138a04170d964da9cdec228e95b976875ae52481Karl Rosaen 120931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public Folder getFolderForTag(Object tag) { 1210dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 121131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int screen = 0; screen < screenCount; screen++) { 121231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 121331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int count = currentScreen.getChildCount(); 121431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 121531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = currentScreen.getChildAt(i); 121631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams(); 121731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) { 121831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project Folder f = (Folder) child; 1219aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (f.getInfo() == tag && f.getInfo().opened) { 122031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return f; 122131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 122231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 122331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 122431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 122531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 122631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 122731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 122831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project public View getViewForTag(Object tag) { 122931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int screenCount = getChildCount(); 123031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int screen = 0; screen < screenCount; screen++) { 123131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project CellLayout currentScreen = ((CellLayout) getChildAt(screen)); 123231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int count = currentScreen.getChildCount(); 123331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project for (int i = 0; i < count; i++) { 123431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project View child = currentScreen.getChildAt(i); 123531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (child.getTag() == tag) { 123631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return child; 123731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 123831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 123931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 124031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return null; 124131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 124231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 124331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 124464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato void removeItems(final ArrayList<ApplicationInfo> apps) { 1245dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 12465c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy final PackageManager manager = getContext().getPackageManager(); 1247629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetManager widgets = AppWidgetManager.getInstance(getContext()); 1248574d20ec84551370987dde530c27ec493bdef564Romain Guy 124964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final HashSet<String> packageNames = new HashSet<String>(); 125064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final int appCount = apps.size(); 125164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (int i = 0; i < appCount; i++) { 125264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato packageNames.add(apps.get(i).componentName.getPackageName()); 125364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 125464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato 1255dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 125631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 1257629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1258629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // Avoid ANRs by treating each screen separately 1259629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy post(new Runnable() { 1260629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy public void run() { 1261629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ArrayList<View> childrenToRemove = new ArrayList<View>(); 1262629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy childrenToRemove.clear(); 1263aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1264629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy int childCount = layout.getChildCount(); 1265629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int j = 0; j < childCount; j++) { 1266629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final View view = layout.getChildAt(j); 1267629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy Object tag = view.getTag(); 1268aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 12690589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (tag instanceof ShortcutInfo) { 12700589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo info = (ShortcutInfo) tag; 1271629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Intent intent = info.intent; 1272629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ComponentName name = intent.getComponent(); 1273aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 127464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 127564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 127664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(name.getPackageName())) { 127764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // TODO: This should probably be done on a worker thread 127864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 127964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato childrenToRemove.add(view); 128064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 128164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1282629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1283629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof UserFolderInfo) { 1284629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final UserFolderInfo info = (UserFolderInfo) tag; 12850589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ArrayList<ShortcutInfo> contents = info.contents; 12860589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(1); 1287629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final int contentsCount = contents.size(); 1288629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy boolean removedFromFolder = false; 1289aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1290629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int k = 0; k < contentsCount; k++) { 12910589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato final ShortcutInfo appInfo = contents.get(k); 1292629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Intent intent = appInfo.intent; 1293629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ComponentName name = intent.getComponent(); 1294aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 129564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 129664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 129764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(name.getPackageName())) { 129864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato toRemove.add(appInfo); 129964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // TODO: This should probably be done on a worker thread 130064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase( 130164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato mLauncher, appInfo); 130264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato removedFromFolder = true; 130364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 130464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1305629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1306629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1307aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1308629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy contents.removeAll(toRemove); 1309629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (removedFromFolder) { 1310629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Folder folder = getOpenFolder(); 1311aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (folder != null) 1312aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung folder.notifyDataSetChanged(); 1313629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1314629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof LiveFolderInfo) { 1315629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final LiveFolderInfo info = (LiveFolderInfo) tag; 1316629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final Uri uri = info.uri; 1317629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final ProviderInfo providerInfo = manager.resolveContentProvider( 1318629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy uri.getAuthority(), 0); 1319629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy 1320f11079b11e98912ed56546eaa300efd06c6eb917Joe Onorato if (providerInfo != null) { 132164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 132264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(providerInfo.packageName)) { 132364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // TODO: This should probably be done on a worker thread 132464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 1325aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung childrenToRemove.add(view); 132664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 132764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1328629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1329629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } else if (tag instanceof LauncherAppWidgetInfo) { 1330629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag; 1331629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy final AppWidgetProviderInfo provider = 1332629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy widgets.getAppWidgetInfo(info.appWidgetId); 1333e1cc6c3745c9ba721b6ab888d74c9d9e1d13ea6aDaniel Sandler if (provider != null) { 133464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato for (String packageName: packageNames) { 133564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (packageName.equals(provider.provider.getPackageName())) { 133664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato // TODO: This should probably be done on a worker thread 133764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato LauncherModel.deleteItemFromDatabase(mLauncher, info); 1338aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung childrenToRemove.add(view); 133964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 134064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1341629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1342574d20ec84551370987dde530c27ec493bdef564Romain Guy } 1343574d20ec84551370987dde530c27ec493bdef564Romain Guy } 1344aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1345629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy childCount = childrenToRemove.size(); 1346629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy for (int j = 0; j < childCount; j++) { 1347629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy View child = childrenToRemove.get(j); 1348629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.removeViewInLayout(child); 1349629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (child instanceof DropTarget) { 1350629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy mDragController.removeDropTarget((DropTarget)child); 1351629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy } 1352574d20ec84551370987dde530c27ec493bdef564Romain Guy } 1353aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1354629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy if (childCount > 0) { 1355629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.requestLayout(); 1356629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy layout.invalidate(); 13575c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy } 135831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1359629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy }); 136031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 136131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1362f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 136364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato void updateShortcuts(ArrayList<ApplicationInfo> apps) { 13649c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato final PackageManager pm = mLauncher.getPackageManager(); 13659c1289cb3bfb74f86e53ec7ac6dd76bb39666b2dJoe Onorato 1366dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka final int screenCount = getChildCount(); 1367dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka for (int i = 0; i < screenCount; i++) { 1368f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final CellLayout layout = (CellLayout) getChildAt(i); 1369f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project int childCount = layout.getChildCount(); 1370f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project for (int j = 0; j < childCount; j++) { 1371f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final View view = layout.getChildAt(j); 1372f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project Object tag = view.getTag(); 13730589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato if (tag instanceof ShortcutInfo) { 13740589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato ShortcutInfo info = (ShortcutInfo)tag; 1375f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // We need to check for ACTION_MAIN otherwise getComponent() might 1376f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // return null for some shortcuts (for instance, for shortcuts to 1377f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project // web pages.) 1378f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final Intent intent = info.intent; 1379f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project final ComponentName name = intent.getComponent(); 1380f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION && 138164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) { 138264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato final int appCount = apps.size(); 1383aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung for (int k = 0; k < appCount; k++) { 138464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato ApplicationInfo app = apps.get(k); 138564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato if (app.componentName.equals(name)) { 138664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato info.setIcon(mIconCache.getIcon(info.intent)); 138764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato ((TextView)view).setCompoundDrawablesWithIntrinsicBounds(null, 138864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato new FastBitmapDrawable(info.getIcon(mIconCache)), 138964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato null, null); 139064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 139164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato } 1392f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1393f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1394f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1395f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1396f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project } 1397f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project 139814f122bf847e50a3e7730ccbe57abc25d086a01bJoe Onorato void moveToDefaultScreen(boolean animate) { 1399c45b16862918a0c6c253bba12032165b030565afJoe Onorato if (animate) { 14004cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka if (mIsSmall) { 14010142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka unshrink(mDefaultPage); 14024cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } else { 14030142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka snapToPage(mDefaultPage); 14044cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka } 1405c45b16862918a0c6c253bba12032165b030565afJoe Onorato } else { 14060142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka setCurrentPage(mDefaultPage); 1407c45b16862918a0c6c253bba12032165b030565afJoe Onorato } 14080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka getChildAt(mDefaultPage).requestFocus(); 140931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 141031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14118a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy void setIndicators(Drawable previous, Drawable next) { 14128a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy mPreviousIndicator = previous; 14138a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy mNextIndicator = next; 14140142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka previous.setLevel(mCurrentPage); 14150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka next.setLevel(mCurrentPage); 14168a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy } 14178a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy 14180142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 14190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public void syncPages() { 14200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka } 142131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 14220142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka @Override 14230142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka public void syncPageItems(int page) { 142431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 14250142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 142631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 1427