Workspace.java revision 1262e369484ce7f2565655ed80e6299232c70bd7
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/*
231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License.
631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at
731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project *
1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and
1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License.
1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17a5902524d4403885eb4c50360bf3465c6be796efJoe Onoratopackage com.android.launcher2;
1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
19af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport com.android.launcher.R;
20495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell
210280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.Animator;
22de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroyimport android.animation.Animator.AnimatorListener;
23b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haaseimport android.animation.AnimatorSet;
240280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.ObjectAnimator;
250280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurkaimport android.animation.PropertyValuesHolder;
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;
47f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectimport android.widget.TextView;
4831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
49af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport java.util.ArrayList;
50af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurkaimport java.util.HashSet;
51edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy
5231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/**
530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * The workspace is a wide area with a wallpaper and a finite number of pages.
540142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka * Each page contains a number of icons, folders or widgets the user can
55aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung * interact with. A workspace is meant to be used with a fixed width only.
5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project */
570142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurkapublic class Workspace extends SmoothPagedView
58dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        implements DropTarget, DragSource, DragScroller, View.OnTouchListener {
59e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy    @SuppressWarnings({"UnusedDeclaration"})
603a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato    private static final String TAG = "Launcher.Workspace";
610142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
62dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    // This is how much the workspace shrinks when we enter all apps or
63dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    // customization mode
64dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    private static final float SHRINK_FACTOR = 0.16f;
65a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
66f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    // Y rotation to apply to the workspace screens
67f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private static final float WORKSPACE_ROTATION = 12.5f;
68a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
69a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen    // These are extra scale factors to apply to the mini home screens
70a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen    // so as to achieve the desired transform
71a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen    private static final float EXTRA_SCALE_FACTOR_0 = 0.97f;
72a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen    private static final float EXTRA_SCALE_FACTOR_1 = 1.0f;
73e54cec82a915c2bc8a7d719228c5d907f3fe14ecAdam Cohen    private static final float EXTRA_SCALE_FACTOR_2 = 1.08f;
74a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
75f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private static final int BACKGROUND_FADE_OUT_DELAY = 300;
76f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private static final int BACKGROUND_FADE_OUT_DURATION = 300;
77f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private static final int BACKGROUND_FADE_IN_DURATION = 100;
78f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
79f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    // These animators are used to fade the
80f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private ObjectAnimator<Float> mBackgroundFadeIn;
81f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private ObjectAnimator<Float> mBackgroundFadeOut;
82f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private float mBackgroundAlpha = 0;
83f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
840142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    private enum ShrinkPosition { SHRINK_TO_TOP, SHRINK_TO_MIDDLE, SHRINK_TO_BOTTOM };
8531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
868f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn    private final WallpaperManager mWallpaperManager;
87aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
880142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    private int mDefaultPage;
8931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka    private boolean mWaitingToShrinkToBottom = false;
9131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
9231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
9331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * CellInfo for the cell that is currently being dragged
9431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
9531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private CellLayout.CellInfo mDragInfo;
96aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
9770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    /**
9870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     * Target drop area calculated during last acceptDrop call.
9970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     */
10070864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    private int[] mTargetCell = null;
10131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1026569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy    /**
1036569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy     * The CellLayout that is currently being dragged over
1046569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy     */
1056569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy    private CellLayout mDragTargetLayout = null;
1066569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
10731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private Launcher mLauncher;
1080589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato    private IconCache mIconCache;
10900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    private DragController mDragController;
110aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
11131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    private int[] mTempCell = new int[2];
11270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    private int[] mTempEstimate = new int[2];
1130280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    private float[] mTempOriginXY = new float[2];
114a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    private float[] mTempDragCoordinates = new float[2];
115a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    private float[] mTempDragBottomRightCoordinates = new float[2];
1160280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    private Matrix mTempInverseMatrix = new Matrix();
11731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
118d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen    private static final int DEFAULT_CELL_COUNT_X = 4;
119d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen    private static final int DEFAULT_CELL_COUNT_Y = 4;
12031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1218a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy    private Drawable mPreviousIndicator;
1228a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy    private Drawable mNextIndicator;
123aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
1241262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    // State variable that indicates whether the pages are small (ie when you're
125dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    // in all apps or customize mode)
126dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    private boolean mIsSmall;
1271262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy
128b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase    private AnimatorListener mUnshrinkAnimationListener;
129dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka
1301262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    private boolean mInScrollArea = false;
1311262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy
13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Used to inflate the Workspace from XML.
13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
13531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param context The application's context.
1360142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka     * @param attrs The attributes set containing the Workspace's customization values.
13731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
13831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public Workspace(Context context, AttributeSet attrs) {
13931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        this(context, attrs, 0);
14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
14131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
14231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
14331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Used to inflate the Workspace from XML.
14431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
14531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param context The application's context.
1460142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka     * @param attrs The attributes set containing the Workspace's customization values.
14731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param defStyle Unused.
14831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
14931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public Workspace(Context context, AttributeSet attrs, int defStyle) {
15031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super(context, attrs, defStyle);
1510142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        mContentIsRefreshable = false;
1525f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka
1535f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        if (!LauncherApplication.isScreenXLarge()) {
1545f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka            mFadeInAdjacentScreens = false;
1555f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        }
15631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1578f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn        mWallpaperManager = WallpaperManager.getInstance(context);
158aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
159aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung        TypedArray a = context.obtainStyledAttributes(attrs,
160aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                R.styleable.Workspace, defStyle, 0);
161d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen        int cellCountX = a.getInt(R.styleable.Workspace_cellCountX, DEFAULT_CELL_COUNT_X);
162d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen        int cellCountY = a.getInt(R.styleable.Workspace_cellCountY, DEFAULT_CELL_COUNT_Y);
1630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        mDefaultPage = a.getInt(R.styleable.Workspace_defaultScreen, 1);
16431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        a.recycle();
16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
166d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen        LauncherModel.updateWorkspaceLayoutCells(cellCountX, cellCountY);
1670d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato        setHapticFeedbackEnabled(false);
1680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
16931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        initWorkspace();
17031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
17131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
17231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
17331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Initializes various states for this workspace.
17431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
1750142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    protected void initWorkspace() {
1760589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        Context context = getContext();
1770142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        mCurrentPage = mDefaultPage;
1780142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        Launcher.setScreen(mCurrentPage);
1790589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        LauncherApplication app = (LauncherApplication)context.getApplicationContext();
1800589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato        mIconCache = app.getIconCache();
18131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
182b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase        mUnshrinkAnimationListener = new AnimatorListener() {
183b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase            public void onAnimationStart(Animator animation) {}
184b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase            public void onAnimationEnd(Animator animation) {
185dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka                mIsSmall = false;
186dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka            }
187b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase            public void onAnimationCancel(Animator animation) {}
188b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase            public void onAnimationRepeat(Animator animation) {}
189dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        };
1900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
1910142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        mSnapVelocity = 600;
19231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
19331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
19431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
195f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    protected int getScrollMode() {
196f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        if (LauncherApplication.isScreenXLarge()) {
197f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            return SmoothPagedView.QUINTIC_MODE;
198f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        } else {
199f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            return SmoothPagedView.OVERSHOOT_MODE;
200f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        }
201f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    }
202f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
203f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    @Override
20431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void addView(View child, int index, LayoutParams params) {
20531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!(child instanceof CellLayout)) {
20631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
20731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
20831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super.addView(child, index, params);
20931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
21031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
21131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
21231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void addView(View child) {
21331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!(child instanceof CellLayout)) {
21431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
21531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
21631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super.addView(child);
21731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
21831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void addView(View child, int index) {
22131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!(child instanceof CellLayout)) {
22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super.addView(child, index);
22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void addView(View child, int width, int height) {
22931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!(child instanceof CellLayout)) {
23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
23131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super.addView(child, width, height);
23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
23631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void addView(View child, LayoutParams params) {
23731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!(child instanceof CellLayout)) {
23831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            throw new IllegalArgumentException("A Workspace can only have CellLayout children.");
23931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
24031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        super.addView(child, params);
24131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
24231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
24331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
24431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @return The open folder on the current screen, or null if there is none
24531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
24631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    Folder getOpenFolder() {
2470142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        CellLayout currentPage = (CellLayout) getChildAt(mCurrentPage);
2480142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        int count = currentPage.getChildCount();
24931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        for (int i = 0; i < count; i++) {
2500142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            View child = currentPage.getChildAt(i);
251aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            if (child instanceof Folder) {
252aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                Folder folder = (Folder) child;
253aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                if (folder.getInfo().opened)
254aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                    return folder;
25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
25631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return null;
25831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
25931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
26031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    ArrayList<Folder> getOpenFolders() {
261dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenCount = getChildCount();
262dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        ArrayList<Folder> folders = new ArrayList<Folder>(screenCount);
26331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
264dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        for (int screen = 0; screen < screenCount; screen++) {
2650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            CellLayout currentPage = (CellLayout) getChildAt(screen);
2660142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            int count = currentPage.getChildCount();
26731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
2680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                View child = currentPage.getChildAt(i);
269aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                if (child instanceof Folder) {
270aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                    Folder folder = (Folder) child;
271aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                    if (folder.getInfo().opened)
272aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                        folders.add(folder);
27331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    break;
27431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
27531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
27631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
27731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
27831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return folders;
27931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
28031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
2810142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    boolean isDefaultPageShowing() {
2820142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        return mCurrentPage == mDefaultPage;
28331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
28431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
28531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
28631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Sets the current screen.
28731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
2880142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka     * @param currentPage
28931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
2900142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    @Override
2910142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    void setCurrentPage(int currentPage) {
2920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        super.setCurrentPage(currentPage);
2930142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        updateWallpaperOffset(mScrollX);
29431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
29531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
29631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
29731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Adds the specified child in the specified screen. The position and dimension of
29831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * the child are defined by x, y, spanX and spanY.
29931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
30031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param child The child to add in one of the workspace's screens.
30131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param screen The screen in which to add the child.
30231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param x The X position of the child in the screen's grid.
30331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param y The Y position of the child in the screen's grid.
30431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param spanX The number of cells spanned horizontally by the child.
30531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param spanY The number of cells spanned vertically by the child.
30631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
30731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void addInScreen(View child, int screen, int x, int y, int spanX, int spanY) {
30831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        addInScreen(child, screen, x, y, spanX, spanY, false);
30931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
31031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
311aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung    void addInFullScreen(View child, int screen) {
312aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung        addInScreen(child, screen, 0, 0, -1, -1);
313aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung    }
314aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
31531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    /**
31631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * Adds the specified child in the specified screen. The position and dimension of
31731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * the child are defined by x, y, spanX and spanY.
31831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     *
31931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param child The child to add in one of the workspace's screens.
32031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param screen The screen in which to add the child.
32131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param x The X position of the child in the screen's grid.
32231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param y The Y position of the child in the screen's grid.
32331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param spanX The number of cells spanned horizontally by the child.
32431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param spanY The number of cells spanned vertically by the child.
32531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     * @param insert When true, the child is inserted at the beginning of the children list.
32631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project     */
32731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void addInScreen(View child, int screen, int x, int y, int spanX, int spanY, boolean insert) {
32831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (screen < 0 || screen >= getChildCount()) {
329291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler            Log.e(TAG, "The screen must be >= 0 and < " + getChildCount()
330291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler                + " (was " + screen + "); skipping child");
331291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandler            return;
33231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
33331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
33431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        final CellLayout group = (CellLayout) getChildAt(screen);
33531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
33631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (lp == null) {
33731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            lp = new CellLayout.LayoutParams(x, y, spanX, spanY);
33831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } else {
33931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            lp.cellX = x;
34031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            lp.cellY = y;
34131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            lp.cellHSpan = spanX;
34231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            lp.cellVSpan = spanY;
34331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
344aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
3456569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        // Get the canonical child id to uniquely represent this view in this screen
346845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka        int childId = LauncherModel.getCellLayoutChildId(-1, screen, x, y, spanX, spanY);
347aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung        if (!group.addViewToCellLayout(child, insert ? 0 : -1, childId, lp)) {
348aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            // TODO: This branch occurs when the workspace is adding views
349aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            // outside of the defined grid
3506569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            // maybe we should be deleting these items from the LauncherModel?
351aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            Log.w(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout");
352aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung        }
353aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
35431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (!(child instanceof Folder)) {
3550d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato            child.setHapticFeedbackEnabled(false);
35631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            child.setOnLongClickListener(mLongClickListener);
35731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
35800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        if (child instanceof DropTarget) {
359aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            mDragController.addDropTarget((DropTarget) child);
36000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        }
36131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
36231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
363dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    public boolean onTouch(View v, MotionEvent event) {
364dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        // this is an intercepted event being forwarded from a cell layout
365dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        if (mIsSmall) {
3662b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy            mLauncher.onWorkspaceClick((CellLayout) v);
36796226223d9849842bb2a67af051acbae9e0677d5Michael Jurka            return true;
368dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        }
369dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        return false;
3700e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka    }
3710e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka
3725f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka    @Override
3735f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka    public boolean dispatchUnhandledMove(View focused, int direction) {
3745f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        if (mIsSmall) {
3755f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka            // when the home screens are shrunken, shouldn't allow side-scrolling
3765f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka            return false;
3775f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        }
3785f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        return super.dispatchUnhandledMove(focused, direction);
3795f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka    }
3805f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka
3815f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka    @Override
3825f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka    public boolean onInterceptTouchEvent(MotionEvent ev) {
3835f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        if (mIsSmall) {
3845f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka            // when the home screens are shrunken, shouldn't allow side-scrolling
3855f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka            return false;
3865f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        }
3875f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        return super.onInterceptTouchEvent(ev);
3885f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka    }
3895f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka
3901262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    protected void onPageBeginMoving() {
3910142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        if (mNextPage != INVALID_PAGE) {
3920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            // we're snapping to a particular screen
39316fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka            enableChildrenCache(mCurrentPage, mNextPage);
3940142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        } else {
3950142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            // this is when user is actively dragging a particular screen, they might
3960142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            // swipe it either left or right (but we won't advance by more than one screen)
39716fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka            enableChildrenCache(mCurrentPage - 1, mCurrentPage + 1);
39831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
399f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        showOutlines();
40031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
40131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
4021262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    protected void onPageEndMoving() {
40316fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka        clearChildrenCache();
4041262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy
4051262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        // Hide the outlines, as long as we're not dragging
4061262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        if (!mDragController.dragging()) {
4071262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            hideOutlines();
4081262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        }
4090142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    }
4100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
4110142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    @Override
4120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    protected void notifyPageSwitchListener() {
4130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        super.notifyPageSwitchListener();
4140142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
4150142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        if (mPreviousIndicator != null) {
4160142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            // if we know the next page, we show the indication for it right away; it looks
4170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            // weird if the indicators are lagging
4180142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            int page = mNextPage;
4190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            if (page == INVALID_PAGE) {
4200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                page = mCurrentPage;
4210142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            }
4220142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            mPreviousIndicator.setLevel(page);
4230142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            mNextIndicator.setLevel(page);
4240142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        }
4250142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        Launcher.setScreen(mCurrentPage);
4260142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    };
4270142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
4288f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn    private void updateWallpaperOffset() {
429798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy        updateWallpaperOffset(getChildAt(getChildCount() - 1).getRight() - (mRight - mLeft));
430798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy    }
431798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy
432798300c4c05b12228f2e4f31c49c3cb728a37889Romain Guy    private void updateWallpaperOffset(int scrollRange) {
43386f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung        final boolean isStaticWallpaper = (mWallpaperManager != null) &&
43486f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung                (mWallpaperManager.getWallpaperInfo() == null);
43586f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung        if (LauncherApplication.isScreenXLarge() && !isStaticWallpaper) {
43686f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung            IBinder token = getWindowToken();
43786f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung            if (token != null) {
43886f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung                mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0 );
43986f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung                mWallpaperManager.setWallpaperOffsets(getWindowToken(),
44086f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung                        Math.max(0.f, Math.min(mScrollX/(float)scrollRange, 1.f)), 0);
44186f7753bbd6d87ce85195b0715e5548edbfdb7d1Winson Chung            }
442956091ba7863bd72086275e61084864994dd6fa7Joe Onorato        }
4438f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn    }
444aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
445f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    private float getScaleXForRotation(float degrees) {
446f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        return (float) (1.0f / Math.cos(Math.PI * degrees / 180.0f));
447f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    }
448f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
449f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    public void showOutlines() {
450f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        if (mBackgroundFadeOut != null) mBackgroundFadeOut.cancel();
451f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        if (mBackgroundFadeIn != null) mBackgroundFadeIn.cancel();
452f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        mBackgroundFadeIn = new ObjectAnimator<Float>(BACKGROUND_FADE_IN_DURATION, this,
453f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                        new PropertyValuesHolder<Float>("backgroundAlpha", 1.0f));
454f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        mBackgroundFadeIn.start();
455f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    }
456f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
457f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    public void hideOutlines() {
458f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        if (mBackgroundFadeIn != null) mBackgroundFadeIn.cancel();
459f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        if (mBackgroundFadeOut != null) mBackgroundFadeOut.cancel();
460f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        mBackgroundFadeOut = new ObjectAnimator<Float>(BACKGROUND_FADE_OUT_DURATION, this,
461f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                        new PropertyValuesHolder<Float>("backgroundAlpha", 0.0f));
462f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        mBackgroundFadeOut.setStartDelay(BACKGROUND_FADE_OUT_DELAY);
463f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        mBackgroundFadeOut.start();
464f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    }
465f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
466f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    public void setBackgroundAlpha(float alpha) {
467f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        mBackgroundAlpha = alpha;
468f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        for (int i = 0; i < getChildCount(); i++) {
469f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            CellLayout cl = (CellLayout) getChildAt(i);
470f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            cl.setBackgroundAlpha(alpha);
471f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        }
472f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    }
473f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
474f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    public float getBackgroundAlpha() {
475f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        return mBackgroundAlpha;
476f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    }
477f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
478f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    @Override
479f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    protected void screenScrolled(int screenCenter) {
4809c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen        CellLayout cur = (CellLayout) getChildAt(mCurrentPage);
4819c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen        CellLayout toRight = (CellLayout) getChildAt(mCurrentPage + 1);
4829c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen        CellLayout toLeft = (CellLayout) getChildAt(mCurrentPage - 1);
483f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
484f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        for (int i = 0; i < mCurrentPage - 1; i++) {
485f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            View v = getChildAt(i);
486f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            if (v != null) {
487f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                v.setRotationY(WORKSPACE_ROTATION);
488f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                v.setScaleX(getScaleXForRotation(WORKSPACE_ROTATION));
489f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            }
490f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        }
491f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        for (int i = mCurrentPage + 1; i < getChildCount(); i++) {
492f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            View v = getChildAt(i);
493f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            if (v != null) {
494f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                v.setRotationY(-WORKSPACE_ROTATION);
495f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                v.setScaleX(getScaleXForRotation(-WORKSPACE_ROTATION));
496f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            }
497f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        }
498f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
4999c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen        int halfScreenSize = getMeasuredWidth() / 2;
500f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        int pageWidth = cur.getMeasuredWidth();
5019c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen        int delta = screenCenter - (getChildOffset(mCurrentPage) -
5029c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen                getRelativeChildOffset(mCurrentPage) + halfScreenSize);
503f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
5049c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen        float scrollProgress = Math.abs(delta/(pageWidth*1.0f + mPageSpacing));
5051262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        boolean scrollRight = (delta <= 0);
506f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
507f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        float rotation;
508f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
5091262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        if (scrollRight) {
510f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            rotation = -scrollProgress * WORKSPACE_ROTATION;
511f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            cur.setRotationY(rotation);
512f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            cur.setScaleX(getScaleXForRotation(rotation));
5139c4949e12c909d5e01d24386147b1c528015b31bAdam Cohen
514f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            if (toLeft != null) {
515f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                rotation = WORKSPACE_ROTATION * (1 - scrollProgress);
516f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toLeft.setRotationY(rotation);
517f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toLeft.setScaleX(getScaleXForRotation(rotation));
518f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            }
519f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            if (toRight != null) {
520f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toRight.setRotationY(-WORKSPACE_ROTATION);
521f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toRight.setScaleX(getScaleXForRotation(WORKSPACE_ROTATION));
522f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            }
523f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        } else {
524f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            rotation = scrollProgress * WORKSPACE_ROTATION;
525f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            cur.setRotationY(rotation);
526f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            cur.setScaleX(getScaleXForRotation(rotation));
527f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
528f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            if (toRight != null) {
529f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                rotation = -WORKSPACE_ROTATION * (1 - scrollProgress);
530f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toRight.setRotationY(rotation);
531f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toRight.setScaleX(getScaleXForRotation(rotation));
532f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            }
533f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            if (toLeft != null) {
534f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toLeft.setRotationY(WORKSPACE_ROTATION);
535f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                toLeft.setScaleX(getScaleXForRotation(WORKSPACE_ROTATION));
536f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            }
537f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen        }
538f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen    }
539f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
54000acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    protected void onAttachedToWindow() {
54100acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        super.onAttachedToWindow();
542956091ba7863bd72086275e61084864994dd6fa7Joe Onorato        computeScroll();
54300acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragController.setWindowToken(getWindowToken());
54400acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    }
54500acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato
54631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
54728750fba6a2d141eb9a1e566718c17236030b815Michael Jurka    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
5480142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        super.onLayout(changed, left, top, right, bottom);
549aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
55079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        // if shrinkToBottom() is called on initialization, it has to be deferred
55179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        // until after the first call to onLayout so that it has the correct width
55279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        if (mWaitingToShrinkToBottom) {
55379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            shrinkToBottom(false);
55479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            mWaitingToShrinkToBottom = false;
55579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        }
55679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka
557aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung        if (LauncherApplication.isInPlaceRotationEnabled()) {
558aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            // When the device is rotated, the scroll position of the current screen
559aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            // needs to be refreshed
5600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            setCurrentPage(getCurrentPage());
561aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung        }
56231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
56331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
56431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
5650142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    protected void dispatchDraw(Canvas canvas) {
5660142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        if (mIsSmall) {
5670142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            // Draw all the workspaces if we're small
5680142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            final int pageCount = getChildCount();
5690142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            final long drawingTime = getDrawingTime();
5700142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            for (int i = 0; i < pageCount; i++) {
5710142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                final View page = (View) getChildAt(i);
5720142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
5730142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                drawChild(canvas, page, drawingTime);
5740142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            }
5750142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        } else {
5760142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            super.dispatchDraw(canvas);
57731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
57831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
57931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
58031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
58131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
582678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato        if (!mLauncher.isAllAppsVisible()) {
58331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Folder openFolder = getOpenFolder();
58431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (openFolder != null) {
58531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                return openFolder.requestFocus(direction, previouslyFocusedRect);
58631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            } else {
5870142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
58831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
58931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
59031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return false;
59131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
59231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
59331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
594c2e24c0a37ddeab930f731c062705d435e477f75Romain Guy    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
595678862186af4ea70d9b4012c9bc127e7fea5e607Joe Onorato        if (!mLauncher.isAllAppsVisible()) {
59631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final Folder openFolder = getOpenFolder();
5970142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            if (openFolder != null) {
59831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                openFolder.addFocusables(views, direction);
5990142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            } else {
6000142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                super.addFocusables(views, direction, focusableMode);
60131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
60231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
60331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
60431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
60531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
6067bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato    public boolean dispatchTouchEvent(MotionEvent ev) {
6077bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
60854dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka            // (In XLarge mode, the workspace is shrunken below all apps, and responds to taps
60954dd75463d0eb47c2f468e19063bdc4141dfdf74Michael Jurka            // ie when you click on a mini-screen, it zooms back to that screen)
6106b4adbc0558fcebbd44998bd00dcd334ddbee32dJoe Onorato            if (!LauncherApplication.isScreenXLarge() && mLauncher.isAllAppsVisible()) {
6117bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato                return false;
6127bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato            }
6137bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato        }
6147bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato        return super.dispatchTouchEvent(ev);
6157bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato    }
6167bb1749c69384faf00b238f0684d3b2e23406451Joe Onorato
6170142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    void enableChildrenCache(int fromPage, int toPage) {
6180142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        if (fromPage > toPage) {
6190142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            final int temp = fromPage;
6200142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            fromPage = toPage;
6210142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            toPage = temp;
6223a2b3f2be58843d26549fb0ec6c6533627c7cd19Mike Cleron        }
623aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
624dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenCount = getChildCount();
625fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell
6260142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        fromPage = Math.max(fromPage, 0);
6270142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        toPage = Math.min(toPage, screenCount - 1);
628fea5d0250767ab938f623a404e6292a32dd2fdf5Adam Powell
6290142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        for (int i = fromPage; i <= toPage; i++) {
63031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final CellLayout layout = (CellLayout) getChildAt(i);
63131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            layout.setChildrenDrawnWithCacheEnabled(true);
63231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            layout.setChildrenDrawingCacheEnabled(true);
63331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
63431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
63531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
63631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void clearChildrenCache() {
637dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenCount = getChildCount();
638dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        for (int i = 0; i < screenCount; i++) {
63931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final CellLayout layout = (CellLayout) getChildAt(i);
64031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            layout.setChildrenDrawnWithCacheEnabled(false);
64131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
64231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
64331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
64431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    @Override
64531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public boolean onTouchEvent(MotionEvent ev) {
6462bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato        if (mLauncher.isAllAppsVisible()) {
6472bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato            // Cancel any scrolling that is in progress.
6482bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato            if (!mScroller.isFinished()) {
6492bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato                mScroller.abortAnimation();
6502bc6b7c2b8b651dde0a65c64c127f5b85c1290d2Joe Onorato            }
6510142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            snapToPage(mCurrentPage);
6527c312c15e33b6cffbda707429e88ade498fc9f5eJoe Onorato            return false; // We don't want the events.  Let them fall through to the all apps view.
65331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
65431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
6550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        return super.onTouchEvent(ev);
65631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
657aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
65801f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka    public boolean isSmall() {
65901f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka        return mIsSmall;
66001f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka    }
66101f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka
6626b509c1fd62a39916bb957eac07917161f549206Patrick Dubroy    void shrinkToTop(boolean animated) {
6630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        shrink(ShrinkPosition.SHRINK_TO_TOP, animated);
66401f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka    }
66501f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka
66601f0ed4126be412c8c4352026dad3b2a49832267Michael Jurka    void shrinkToMiddle() {
6670142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        shrink(ShrinkPosition.SHRINK_TO_MIDDLE, true);
668213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka    }
669213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka
670213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka    void shrinkToBottom() {
67179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        shrinkToBottom(true);
67279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka    }
67379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka
67479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka    void shrinkToBottom(boolean animated) {
67579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        if (mFirstLayout) {
67679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            // (mFirstLayout == "first layout has not happened yet")
67779212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            // if we get a call to shrink() as part of our initialization (for example, if
67879212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            // Launcher is started in All Apps mode) then we need to wait for a layout call
67979212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            // to get our width so we can layout the mini-screen views correctly
68079212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            mWaitingToShrinkToBottom = true;
68179212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        } else {
6820142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            shrink(ShrinkPosition.SHRINK_TO_BOTTOM, animated);
68379212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka        }
684213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka    }
685213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka
686a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen    private float getYScaleForScreen(int screen) {
687a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        int x = Math.abs(screen - 2);
688a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
689a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        // TODO: This should be generalized for use with arbitrary rotation angles.
690a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        switch(x) {
691a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen            case 0: return EXTRA_SCALE_FACTOR_0;
692a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen            case 1: return EXTRA_SCALE_FACTOR_1;
693a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen            case 2: return EXTRA_SCALE_FACTOR_2;
694a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        }
695a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        return 1.0f;
696a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen    }
697a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
698dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    // we use this to shrink the workspace for the all apps view and the customize view
6990142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    private void shrink(ShrinkPosition shrinkPosition, boolean animated) {
700dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        mIsSmall = true;
7015f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        // we intercept and reject all touch events when we're small, so be sure to reset the state
7025f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        mTouchState = TOUCH_STATE_REST;
7035f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        mActivePointerId = INVALID_POINTER;
7045f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka
7057247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy        final Resources res = getResources();
706dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenWidth = getWidth();
707213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka        final int screenHeight = getHeight();
7080142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
7090142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        // Making the assumption that all pages have the same width as the 0th
7100142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        final int pageWidth = getChildAt(0).getMeasuredWidth();
7110142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        final int pageHeight = getChildAt(0).getMeasuredHeight();
7120142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
7130142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        final int scaledPageWidth = (int) (SHRINK_FACTOR * pageWidth);
7140142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        final int scaledPageHeight = (int) (SHRINK_FACTOR * pageHeight);
715a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        final float extraScaledSpacing = res.getDimension(R.dimen.smallScreenExtraSpacing);
716dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka
717dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenCount = getChildCount();
718a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        float totalWidth = screenCount * scaledPageWidth + (screenCount - 1) * extraScaledSpacing;
719213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka
720213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka        float newY = getResources().getDimension(R.dimen.smallScreenVerticalMargin);
7210142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        if (shrinkPosition == ShrinkPosition.SHRINK_TO_BOTTOM) {
7220142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            newY = screenHeight - newY - scaledPageHeight;
7230142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        } else if (shrinkPosition == ShrinkPosition.SHRINK_TO_MIDDLE) {
7240142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            newY = screenHeight / 2 - scaledPageHeight / 2;
725213d96354e7407dba5c9715eb10d04bebd82c395Michael Jurka        }
726dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka
727dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        // We animate all the screens to the centered position in workspace
728dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        // At the same time, the screens become greyed/dimmed
729dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka
730dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        // newX is initialized to the left-most position of the centered screens
7310142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        float newX = mScroller.getFinalX() + screenWidth / 2 - totalWidth / 2;
732a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
733a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        // We are going to scale about the center of the view, so we need to adjust the positions
734a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        // of the views accordingly
735a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        newX -= (pageWidth - scaledPageWidth) / 2.0f;
736a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen        newY -= (pageHeight - scaledPageHeight) / 2.0f;
737dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        for (int i = 0; i < screenCount; i++) {
738dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka            CellLayout cl = (CellLayout) getChildAt(i);
739a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
740f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen            float rotation = (-i + 2) * WORKSPACE_ROTATION;
741a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen            float rotationScaleX = (float) (1.0f / Math.cos(Math.PI * rotation / 180.0f));
742a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen            float rotationScaleY = getYScaleForScreen(i);
743a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen
74479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            if (animated) {
7457247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy                final int duration = res.getInteger(R.integer.config_workspaceShrinkTime);
7465f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                new ObjectAnimator<Float>(duration, cl,
7475f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                        new PropertyValuesHolder<Float>("x", newX),
7485f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                        new PropertyValuesHolder<Float>("y", newY),
749e54cec82a915c2bc8a7d719228c5d907f3fe14ecAdam Cohen                        new PropertyValuesHolder<Float>("scaleX", SHRINK_FACTOR * rotationScaleX),
750e54cec82a915c2bc8a7d719228c5d907f3fe14ecAdam Cohen                        new PropertyValuesHolder<Float>("scaleY", SHRINK_FACTOR * rotationScaleY),
7515f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                        new PropertyValuesHolder<Float>("backgroundAlpha", 1.0f),
75216fed41e5e680c547b23e108788eb85f1b04d36dMichael Jurka                        new PropertyValuesHolder<Float>("alpha", 1.0f),
7535f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                        new PropertyValuesHolder<Float>("rotationY", rotation)).start();
75479212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            } else {
75579212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka                cl.setX((int)newX);
75679212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka                cl.setY((int)newY);
757f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                cl.setScaleX(SHRINK_FACTOR * rotationScaleX);
758f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                cl.setScaleY(SHRINK_FACTOR * rotationScaleY);
7595f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                cl.setBackgroundAlpha(1.0f);
7605f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                cl.setAlpha(0.0f);
761a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen                cl.setRotationY(rotation);
76279212d81361d1ad8c941c48f8323eb526643ca68Michael Jurka            }
763dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka            // increment newX for the next screen
764a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen            newX += scaledPageWidth + extraScaledSpacing;
765dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka            cl.setOnInterceptTouchListener(this);
766dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        }
767dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        setChildrenDrawnWithCacheEnabled(true);
768dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    }
769dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka
770dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    // We call this when we trigger an unshrink by clicking on the CellLayout cl
7712b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy    public void unshrink(CellLayout clThatWasClicked) {
7720142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        int newCurrentPage = mCurrentPage;
7734cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka        final int screenCount = getChildCount();
7744cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka        for (int i = 0; i < screenCount; i++) {
7754cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka            if (getChildAt(i) == clThatWasClicked) {
7760142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                newCurrentPage = i;
7774cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka            }
7784cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka        }
7790142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        unshrink(newCurrentPage);
7804cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka    }
7814cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka
7820142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    private void unshrink(int newCurrentPage) {
783b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka        if (mIsSmall) {
7845f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka            int newX = getChildOffset(newCurrentPage) - getRelativeChildOffset(newCurrentPage);
7855f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka            int delta = newX - mScrollX;
7864cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka
787b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            final int screenCount = getChildCount();
788b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            for (int i = 0; i < screenCount; i++) {
789b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka                CellLayout cl = (CellLayout) getChildAt(i);
790b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka                cl.setX(cl.getX() + delta);
791b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            }
7920142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            snapToPage(newCurrentPage);
793b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            unshrink();
7940142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
7950142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            setCurrentPage(newCurrentPage);
796b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka        }
797dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    }
798dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka
7994cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka    void unshrink() {
8004cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka        unshrink(true);
8014cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka    }
8024cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka
8034cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka    void unshrink(boolean animated) {
804b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka        if (mIsSmall) {
805b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase            AnimatorSet s = new AnimatorSet();
806b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            final int screenCount = getChildCount();
8074cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka
8084cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka            final int duration = getResources().getInteger(R.integer.config_workspaceUnshrinkTime);
809b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            for (int i = 0; i < screenCount; i++) {
8107247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy                final CellLayout cl = (CellLayout)getChildAt(i);
8115f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                float finalAlphaValue = (i == mCurrentPage) ? 1.0f : 0.0f;
812f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                float rotation = 0.0f;
813f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
814f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                if (i < mCurrentPage) {
815f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                    rotation = WORKSPACE_ROTATION;
816f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                } else if (i > mCurrentPage) {
817f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                    rotation = -WORKSPACE_ROTATION;
818f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                }
819f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen
8204cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                if (animated) {
8214cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                    s.playTogether(
822b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase                            new ObjectAnimator<Float>(duration, cl, "translationX", 0.0f),
823b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase                            new ObjectAnimator<Float>(duration, cl, "translationY", 0.0f),
824b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase                            new ObjectAnimator<Float>(duration, cl, "scaleX", 1.0f),
825b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase                            new ObjectAnimator<Float>(duration, cl, "scaleY", 1.0f),
8265f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                            new ObjectAnimator<Float>(duration, cl, "backgroundAlpha", 0.0f),
8275f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                            new ObjectAnimator<Float>(duration, cl, "alpha", finalAlphaValue),
828f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                            new ObjectAnimator<Float>(duration, cl, "rotationY", rotation));
8294cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                } else {
8304cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                    cl.setTranslationX(0.0f);
8314cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                    cl.setTranslationY(0.0f);
8324cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                    cl.setScaleX(1.0f);
8334cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                    cl.setScaleY(1.0f);
8345f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka                    cl.setBackgroundAlpha(0.0f);
835f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                    cl.setAlpha(finalAlphaValue);
836f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen                    cl.setRotationY(rotation);
8374cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka                }
838b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            }
839b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            s.addListener(mUnshrinkAnimationListener);
840b0f28bd9a52fa4e343c8299d1c3e225d8e01c1e9Michael Jurka            s.start();
841dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        }
842dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka    }
843dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka
84431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void startDrag(CellLayout.CellInfo cellInfo) {
84531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        View child = cellInfo.cell;
846aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
84731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        // Make sure the drag was started by a long press as opposed to a long click.
8487984c9496bcaeca23ee7fdecc4d4f1bb2467e0f2Bjorn Bringert        if (!child.isInTouchMode()) {
84931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            return;
85031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
851aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
85231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDragInfo = cellInfo;
8530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        mDragInfo.screen = mCurrentPage;
854aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
8550142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        CellLayout current = ((CellLayout) getChildAt(mCurrentPage));
85631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
85731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        current.onDragChild(child);
85800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragController.startDrag(child, this, child.getTag(), DragController.DRAG_ACTION_MOVE);
859de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        current.onDragEnter(child);
86031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        invalidate();
86131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
86231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8630280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    void addApplicationShortcut(ShortcutInfo info, int screen, int cellX, int cellY,
8640280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            boolean insertAtFirst, int intersectX, int intersectY) {
8650280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        final CellLayout cellLayout = (CellLayout) getChildAt(screen);
8660280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        View view = mLauncher.createShortcut(R.layout.application, cellLayout, (ShortcutInfo) info);
86731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        final int[] cellXY = new int[2];
8690280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        cellLayout.findCellForSpanThatIntersects(cellXY, 1, 1, intersectX, intersectY);
8700280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        addInScreen(view, screen, cellXY[0], cellXY[1], 1, 1, insertAtFirst);
8710280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
8720280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
8730280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                cellXY[0], cellXY[1]);
87431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
87531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
8760280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
87700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
87800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            DragView dragView, Object dragInfo) {
8790280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        CellLayout cellLayout;
880a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        int originX = x - xOffset;
881a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        int originY = y - yOffset;
882a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        if (mIsSmall) {
8830280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            cellLayout = findMatchingPageForDragOver(dragView, originX, originY);
884a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            if (cellLayout == null) {
885a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                // cancel the drag if we're not over a mini-screen at time of drop
886a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                // TODO: maybe add a nice fade here?
887a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                return;
888a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            }
8890280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            // get originX and originY in the local coordinate system of the screen
8900280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mTempOriginXY[0] = originX;
8910280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mTempOriginXY[1] = originY;
8920280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mapPointGlobalToLocal(cellLayout, mTempOriginXY);
8930280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            originX = (int)mTempOriginXY[0];
8940280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            originY = (int)mTempOriginXY[1];
8950280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        } else {
8960280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            cellLayout = getCurrentDropLayout();
897a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        }
898c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka
89931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        if (source != this) {
900a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            onDropExternal(originX, originY, dragInfo, cellLayout);
90131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } else {
90231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            // Move internally
90331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (mDragInfo != null) {
90431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final View cell = mDragInfo.cell;
905a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
9066a1435d78d5133b1f37274c4d358bf6d22e10229Michael Jurka                mTargetCell = findNearestVacantArea(originX, originY,
907aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                        mDragInfo.spanX, mDragInfo.spanY, cell, cellLayout,
908aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                        mTargetCell);
909c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka
910c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                int screen = indexOfChild(cellLayout);
911c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                if (screen != mDragInfo.screen) {
912c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                    final CellLayout originalCellLayout = (CellLayout) getChildAt(mDragInfo.screen);
913c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                    originalCellLayout.removeView(cell);
914c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                    addInScreen(cell, screen, mTargetCell[0], mTargetCell[1],
915c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                            mDragInfo.spanX, mDragInfo.spanY);
916c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                }
917aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                cellLayout.onDropChild(cell);
91831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
919aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                // update the item's position after drop
92084f296c106cb1c7b6d3ae6c6d5508a17f1324e29Romain Guy                final ItemInfo info = (ItemInfo) cell.getTag();
9210280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) cell.getLayoutParams();
9220280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                cellLayout.onMove(cell, mTargetCell[0], mTargetCell[1]);
923aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                lp.cellX = mTargetCell[0];
924aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                lp.cellY = mTargetCell[1];
92560587efe1a60ed698db9e2cafcd48f2c3fc8aa40Michael Jurka                cell.setId(LauncherModel.getCellLayoutChildId(-1, mDragInfo.screen,
926845ba3b17b83a2b11d79c6fb076cf96ab4a737dfMichael Jurka                        mTargetCell[0], mTargetCell[1], mDragInfo.spanX, mDragInfo.spanY));
927aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
92831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                LauncherModel.moveItemInDatabase(mLauncher, info,
929c6ee42e25f203e408826e7eab4ad8faf67ed2ff9Michael Jurka                        LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
930aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                        lp.cellX, lp.cellY);
93131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
93231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
93331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
93431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
935aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung    public void onDragEnter(DragSource source, int x, int y, int xOffset,
936aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            int yOffset, DragView dragView, Object dragInfo) {
937de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy        getCurrentDropLayout().onDragEnter(dragView);
9381262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        showOutlines();
93931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
94031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
941440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy    public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
9426569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            DragView dragView, Object dragInfo) {
9436569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
9440280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        if (mIsSmall) {
9450280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            // If we're shrunken, don't let anyone drag on folders/etc  that are on the mini-screens
9460280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            return null;
9470280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        }
948440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        // We may need to delegate the drag to a child view. If a 1x1 item
949440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        // would land in a cell occupied by a DragTarget (e.g. a Folder),
950440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        // then drag events should be handled by that child.
951440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy
9526569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        ItemInfo item = (ItemInfo)dragInfo;
953440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        CellLayout currentLayout = getCurrentDropLayout();
954440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy
955440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        int dragPointX, dragPointY;
956440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        if (item.spanX == 1 && item.spanY == 1) {
957440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            // For a 1x1, calculate the drop cell exactly as in onDragOver
958440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            dragPointX = x - xOffset;
959440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            dragPointY = y - yOffset;
960440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        } else {
961440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            // Otherwise, use the exact drag coordinates
962440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            dragPointX = x;
963440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            dragPointY = y;
964440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        }
9650280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        dragPointX += mScrollX - currentLayout.getLeft();
9660280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        dragPointY += mScrollY - currentLayout.getTop();
967440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy
968440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        // If we are dragging over a cell that contains a DropTarget that will
969440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        // accept the drop, delegate to that DropTarget.
970440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        final int[] cellXY = mTempCell;
971440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        currentLayout.estimateDropCell(dragPointX, dragPointY, item.spanX, item.spanY, cellXY);
972440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        View child = currentLayout.getChildAt(cellXY[0], cellXY[1]);
973440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        if (child instanceof DropTarget) {
974440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            DropTarget target = (DropTarget)child;
975440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            if (target.acceptDrop(source, x, y, xOffset, yOffset, dragView, dragInfo)) {
976440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy                return target;
977440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            }
978440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        }
979440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy        return null;
980440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy    }
9816569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
9820280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    private void mapPointGlobalToLocal(View v, float[] xy) {
9830280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        xy[0] = xy[0] + mScrollX - v.getLeft();
9840280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        xy[1] = xy[1] + mScrollY - v.getTop();
9850280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        v.getMatrix().invert(mTempInverseMatrix);
9860280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        mTempInverseMatrix.mapPoints(xy);
9870280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    }
9880280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
989a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    // xy = upper left corner of item being dragged
990a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    // bottomRightXy = lower right corner of item being dragged
991a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    // This method will see which mini-screen is most overlapped by the item being dragged, and
992a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    // return it. It will also transform the parameters xy and bottomRightXy into the local
993a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    // coordinate space of the returned screen
9940280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    private CellLayout findMatchingPageForDragOver(DragView dragView, int originX, int originY) {
9950280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        float x = originX + dragView.getScaledDragRegionXOffset();
9960280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        float y = originY + dragView.getScaledDragRegionYOffset();
9970280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        float right = x + dragView.getScaledDragRegionWidth();
9980280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        float bottom = y + dragView.getScaledDragRegionHeight();
999a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
1000a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        // We loop through all the screens (ie CellLayouts) and see which one overlaps the most
1001a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        // with the item being dragged.
1002a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        final int screenCount = getChildCount();
1003a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        CellLayout bestMatchingScreen = null;
10040280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        float smallestDistSoFar = Float.MAX_VALUE;
10050280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        final float[] xy = mTempDragCoordinates;
10060280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        final float[] bottomRightXy = mTempDragBottomRightCoordinates;
1007a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        for (int i = 0; i < screenCount; i++) {
1008a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            CellLayout cl = (CellLayout)getChildAt(i);
1009a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            // Transform the coordinates of the item being dragged to the CellLayout's coordinates
1010a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float left = cl.getLeft();
1011a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float top = cl.getTop();
1012a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            xy[0] = x + mScrollX - left;
1013a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            xy[1] = y + mScrollY - top;
1014a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
1015a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            bottomRightXy[0] = right + mScrollX - left;
1016a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            bottomRightXy[1] = bottom + mScrollY - top;
1017a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
10180280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            cl.getMatrix().invert(mTempInverseMatrix);
10190280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mTempInverseMatrix.mapPoints(xy);
10200280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mTempInverseMatrix.mapPoints(bottomRightXy);
1021a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
1022a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float dragRegionX = xy[0];
1023a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float dragRegionY = xy[1];
1024a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float dragRegionRight = bottomRightXy[0];
1025a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float dragRegionBottom = bottomRightXy[1];
10260280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            float dragRegionCenterX = (dragRegionX + dragRegionRight) / 2.0f;
10270280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            float dragRegionCenterY = (dragRegionY + dragRegionBottom) / 2.0f;
1028a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
1029a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            // Find the overlapping region
1030a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float overlapLeft = Math.max(0f, dragRegionX);
1031a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float overlapTop = Math.max(0f, dragRegionY);
1032a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float overlapBottom = Math.min(cl.getHeight(), dragRegionBottom);
1033a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            float overlapRight = Math.min(cl.getWidth(), dragRegionRight);
1034a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            if (overlapRight >= 0 && overlapLeft <= cl.getWidth() &&
10350280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    (overlapTop >= 0 && overlapBottom <= cl.getHeight())) {
10360280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                // Calculate the distance between the two centers
10370280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                float distX = dragRegionCenterX - cl.getWidth()/2;
10380280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                float distY = dragRegionCenterY - cl.getHeight()/2;
10390280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                float dist = distX * distX + distY * distY;
10400280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
1041a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                float overlap = (overlapRight - overlapLeft) * (overlapBottom - overlapTop);
10420280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
10430280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                // Calculate the closest overlapping region
10440280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                if (overlap > 0 && dist < smallestDistSoFar) {
10450280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    smallestDistSoFar = dist;
1046a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                    bestMatchingScreen = cl;
1047a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                }
1048a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka             }
1049a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        }
10500280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
10510280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        if (bestMatchingScreen != mDragTargetLayout) {
1052a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            if (mDragTargetLayout != null) {
10530280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                mDragTargetLayout.onDragExit();
1054a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            }
1055a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            mDragTargetLayout = bestMatchingScreen;
10561262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            // TODO: Should we be calling mDragTargetLayout.onDragEnter() here?
1057a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        }
1058a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        return bestMatchingScreen;
1059a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka    }
1060a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
1061440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy    public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
1062440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy            DragView dragView, Object dragInfo) {
10630280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        CellLayout currentLayout;
10640280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        int originX = x - xOffset;
10650280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        int originY = y - yOffset;
10660280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        if (mIsSmall) {
10670280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            currentLayout = findMatchingPageForDragOver(dragView, originX, originY);
10680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
10690280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            if (currentLayout == null) {
10700280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                return;
10710280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            }
10720280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
10730280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            currentLayout.setHover(true);
10740280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            // get originX and originY in the local coordinate system of the screen
10750280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mTempOriginXY[0] = originX;
10760280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mTempOriginXY[1] = originY;
10770280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mapPointGlobalToLocal(currentLayout, mTempOriginXY);
10780280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            originX = (int)mTempOriginXY[0];
10790280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            originY = (int)mTempOriginXY[1];
10800280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        } else {
10810280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            currentLayout = getCurrentDropLayout();
10820280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        }
1083440c360bc395c43683fa9ca226e59f9e35f9e926Patrick Dubroy
1084976ebec9e31643d3513f9f0de2b433d9aa186ce9Patrick Dubroy        final ItemInfo item = (ItemInfo)dragInfo;
10856569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
10866569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        if (dragInfo instanceof LauncherAppWidgetInfo) {
10876569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo)dragInfo;
10886569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
10896569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            if (widgetInfo.spanX == -1) {
10906569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy                // Calculate the grid spans needed to fit this widget
10918f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy                int[] spans = currentLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, null);
10926569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy                item.spanX = spans[0];
10936569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy                item.spanY = spans[1];
10946569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            }
10956569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        }
1096a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
1097a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        if (source != this) {
1098a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            // This is a hack to fix the point used to determine which cell an icon from the all
1099a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            // apps screen is over
1100a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            if (item != null && item.spanX == 1 && currentLayout != null) {
1101a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                int dragRegionLeft = (dragView.getWidth() - currentLayout.getCellWidth()) / 2;
1102a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka
1103a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                originX += dragRegionLeft - dragView.getDragRegionLeft();
1104a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                if (dragView.getDragRegionWidth() != currentLayout.getCellWidth()) {
1105a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                    dragView.setDragRegion(dragView.getDragRegionLeft(), dragView.getDragRegionTop(),
1106a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                            currentLayout.getCellWidth(), dragView.getDragRegionHeight());
1107a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka                }
1108a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka            }
1109a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka        }
11101262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy
11111262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        // When touch is inside the scroll area, skip dragOver actions for the current screen
11121262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        if (!mInScrollArea) {
11131262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            if (currentLayout != mDragTargetLayout) {
11141262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                if (mDragTargetLayout != null) {
11151262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                    mDragTargetLayout.onDragExit();
11161262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                }
1117de7658b5e02ae10010e44fcf8d9c5814f54d9eb0Patrick Dubroy                currentLayout.onDragEnter(dragView);
11181262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                mDragTargetLayout = currentLayout;
11196569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            }
11206569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
11211262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            // only visualize the drop locations for moving icons within the home screen on tablet
11221262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            // on phone, we also visualize icons dragged in from All Apps
11231262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            if ((!LauncherApplication.isScreenXLarge() || source == this)
11241262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                    && mDragTargetLayout != null) {
11251262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                final View child = (mDragInfo == null) ? null : mDragInfo.cell;
11261262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                int localOriginX = originX - (mDragTargetLayout.getLeft() - mScrollX);
11271262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                int localOriginY = originY - (mDragTargetLayout.getTop() - mScrollY);
11281262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                mDragTargetLayout.visualizeDropLocation(
11291262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy                        child, localOriginX, localOriginY, item.spanX, item.spanY);
11301262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            }
1131976ebec9e31643d3513f9f0de2b433d9aa186ce9Patrick Dubroy        }
113231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
113331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1134aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung    public void onDragExit(DragSource source, int x, int y, int xOffset,
1135aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            int yOffset, DragView dragView, Object dragInfo) {
11366569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        if (mDragTargetLayout != null) {
11370280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mDragTargetLayout.onDragExit();
11386569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            mDragTargetLayout = null;
11396569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        }
11401262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        if (!mIsPageMoving) {
11411262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            hideOutlines();
11421262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        }
114331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
114431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1145aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung    private void onDropExternal(int x, int y, Object dragInfo,
1146aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            CellLayout cellLayout) {
114731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        onDropExternal(x, y, dragInfo, cellLayout, false);
114831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1149aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
11502b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy    /**
11512b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy     * Add the item specified by dragInfo to the given layout.
11522b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy     * This is basically the equivalent of onDropExternal, except it's not initiated
11532b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy     * by drag and drop.
11542b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy     * @return true if successful
11552b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy     */
11562b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy    public boolean addExternalItemToScreen(Object dragInfo, View layout) {
11572b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy        CellLayout cl = (CellLayout) layout;
11582b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy        ItemInfo info = (ItemInfo) dragInfo;
11592b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy
11600280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        if (cl.findCellForSpan(mTempEstimate, info.spanX, info.spanY)) {
11612b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy            onDropExternal(0, 0, dragInfo, cl, false);
11622b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy            return true;
11632b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy        }
11640280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        mLauncher.showOutOfSpaceMessage();
11652b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy        return false;
11662b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy    }
11672b9ff37edb3f5965559b3ff7d37e418b4a2917a1Patrick Dubroy
11680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    // Drag from somewhere else
1169aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung    private void onDropExternal(int x, int y, Object dragInfo,
1170aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            CellLayout cellLayout, boolean insertAtFirst) {
11710280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        int screen = indexOfChild(cellLayout);
11720280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        if (dragInfo instanceof PendingAddItemInfo) {
11730280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            PendingAddItemInfo info = (PendingAddItemInfo) dragInfo;
11740280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            // When dragging and dropping from customization tray, we deal with creating
11750280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            // widgets/shortcuts/folders in a slightly different way
11760280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            int[] touchXY = new int[2];
11770280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            touchXY[0] = x;
11780280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            touchXY[1] = y;
11790280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            switch (info.itemType) {
11800280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
11810280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    mLauncher.addAppWidgetFromDrop(info.componentName, screen, touchXY);
11820280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    break;
11830280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                case LauncherSettings.Favorites.ITEM_TYPE_LIVE_FOLDER:
11840280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    mLauncher.addLiveFolderFromDrop(info.componentName, screen, touchXY);
11850280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    break;
11860280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
11870280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    mLauncher.processShortcutFromDrop(info.componentName, screen, touchXY);
11880280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    break;
11890280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                default:
11900280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    throw new IllegalStateException("Unknown item type: " + info.itemType);
11910280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            }
11920280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            cellLayout.onDragExit();
11930280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            return;
11940280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        }
11950280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
11960280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        // This is for other drag/drop cases, like dragging from All Apps
119731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        ItemInfo info = (ItemInfo) dragInfo;
119831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1199af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka        View view = null;
120031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
120131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        switch (info.itemType) {
120231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
120331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
1204e48e7c1a62e6a367803dca62c8fce9de57121b0fJoe Onorato            if (info.container == NO_ID && info instanceof ApplicationInfo) {
120531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                // Came from all apps -- make a copy
1206aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                info = new ShortcutInfo((ApplicationInfo) info);
120731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
1208aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            view = mLauncher.createShortcut(R.layout.application, cellLayout,
1209aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                    (ShortcutInfo) info);
121031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            break;
121131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        case LauncherSettings.Favorites.ITEM_TYPE_USER_FOLDER:
121231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher,
12130280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    cellLayout, ((UserFolderInfo) info));
1214af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka            break;
121531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        default:
12160280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            throw new IllegalStateException("Unknown item type: " + info.itemType);
121731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
121831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
12196569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        // If the view is null, it has already been added.
12206569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        if (view == null) {
12210280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            cellLayout.onDragExit();
12226569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy        } else {
12237ded67cd64153cd41bb133a6aab11b3254b4a5d9Michael Jurka            mTargetCell = findNearestVacantArea(x, y, 1, 1, null, cellLayout, mTargetCell);
1224aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            addInScreen(view, indexOfChild(cellLayout), mTargetCell[0],
1225aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                    mTargetCell[1], info.spanX, info.spanY, insertAtFirst);
1226aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung            cellLayout.onDropChild(view);
12276569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy            CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
122831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
1229af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka            LauncherModel.addOrMoveItemInDatabase(mLauncher, info,
12300280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                    LauncherSettings.Favorites.CONTAINER_DESKTOP, screen,
1231aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                    lp.cellX, lp.cellY);
1232af44209bfa60da3c7ab49b7f508f9effd316ee41Michael Jurka        }
123331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1234aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
123570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    /**
123670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     * Return the current {@link CellLayout}, correctly picking the destination
123770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     * screen while a scroll is in progress.
123870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     */
123970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    private CellLayout getCurrentDropLayout() {
12400142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        int index = mScroller.isFinished() ? mCurrentPage : mNextPage;
124170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey        return (CellLayout) getChildAt(index);
124270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    }
124331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
124470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    /**
12450280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka     * Return the current CellInfo describing our current drag; this method exists
12460280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka     * so that Launcher can sync this object with the correct info when the activity is created/
12470280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka     * destroyed
12480280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka     *
12490280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka     */
12500280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    public CellLayout.CellInfo getDragInfo() {
12510280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        return mDragInfo;
12520280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    }
12530280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
12540280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    /**
125570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     * {@inheritDoc}
125670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     */
125770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    public boolean acceptDrop(DragSource source, int x, int y,
125800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato            int xOffset, int yOffset, DragView dragView, Object dragInfo) {
12590280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        CellLayout layout;
12600280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        if (mIsSmall) {
12610280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            layout = findMatchingPageForDragOver(dragView, x - xOffset, y - yOffset);
12620280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            if (layout == null) {
12630280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                // cancel the drag if we're not over a mini-screen at time of drop
12640280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka                return false;
12650280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            }
12660280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        } else {
12670280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            layout = getCurrentDropLayout();
12680280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        }
1269c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka        final CellLayout.CellInfo dragCellInfo = mDragInfo;
1270c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka        final int spanX = dragCellInfo == null ? 1 : dragCellInfo.spanX;
1271c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka        final int spanY = dragCellInfo == null ? 1 : dragCellInfo.spanY;
12724c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy
1273c28de51eedb26848abf9245ddd19e021d30be318Michael Jurka        final View ignoreView = dragCellInfo == null ? null : dragCellInfo.cell;
12744c58c485d8c02f8ca7e8b4d93140440f6a3a5131Romain Guy
12750280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        if (layout.findCellForSpanIgnoring(null, spanX, spanY, ignoreView)) {
12760e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka            return true;
12770e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka        } else {
12780280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka            mLauncher.showOutOfSpaceMessage();
12790e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka            return false;
12800e26059548e429e5d1c973bebe4c561bead2926fMichael Jurka        }
128170864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    }
1282aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
128370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    /**
128470864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     * Calculate the nearest cell where the given object would be dropped.
128570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey     */
12866a1435d78d5133b1f37274c4d358bf6d22e10229Michael Jurka    private int[] findNearestVacantArea(int pixelX, int pixelY,
128770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey            int spanX, int spanY, View ignoreView, CellLayout layout, int[] recycle) {
12886569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
12895f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        int localPixelX = pixelX - (layout.getLeft() - mScrollX);
12905f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka        int localPixelY = pixelY - (layout.getTop() - mScrollY);
12916569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy
129270864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey        // Find the best target drop location
12930280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        return layout.findNearestVacantArea(
1294fc9f07d42511231a26fa182c32e2efaa0f41d478Michael Jurka                localPixelX, localPixelY, spanX, spanY, ignoreView, recycle);
129570864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey    }
1296aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
12978f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy    /**
12988f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy     * Estimate the size that a child with the given dimensions will take in the current screen.
12998f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy     */
13008f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy    void estimateChildSize(int minWidth, int minHeight, int[] result) {
13010142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        ((CellLayout)getChildAt(mCurrentPage)).estimateChildSize(minWidth, minHeight, result);
13028f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy    }
13038f86ddcb90063a56c25c9c782316574bc4e5dd93Patrick Dubroy
130431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    void setLauncher(Launcher launcher) {
130531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mLauncher = launcher;
130631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
130731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
130800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato    public void setDragController(DragController dragController) {
130900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato        mDragController = dragController;
131031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
131131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
131231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void onDropCompleted(View target, boolean success) {
1313aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung        if (success) {
131431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (target != this && mDragInfo != null) {
131531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
131631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                cellLayout.removeView(mDragInfo.cell);
131700acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                if (mDragInfo.cell instanceof DropTarget) {
131800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                    mDragController.removeDropTarget((DropTarget)mDragInfo.cell);
131900acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato                }
1320aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                // final Object tag = mDragInfo.cell.getTag();
132131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
132231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        } else {
132331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            if (mDragInfo != null) {
132431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                final CellLayout cellLayout = (CellLayout) getChildAt(mDragInfo.screen);
132531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                cellLayout.onDropAborted(mDragInfo.cell);
132631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
132731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
132831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
132931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        mDragInfo = null;
133031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
133131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13320280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    public boolean isDropEnabled() {
13330280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka        return true;
13340280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka    }
13350280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka
13360142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    @Override
13370142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    protected void onRestoreInstanceState(Parcelable state) {
13380142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        super.onRestoreInstanceState(state);
13390142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        Launcher.setScreen(mCurrentPage);
13400142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    }
13410142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
13420142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    @Override
134331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void scrollLeft() {
13447f0f4f3c35fe0b6a94504ec39ac127fa935282efMichael Jurka        if (!mIsSmall) {
13450142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            super.scrollLeft();
134631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
134731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
134831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
13490142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    @Override
135031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public void scrollRight() {
13517f0f4f3c35fe0b6a94504ec39ac127fa935282efMichael Jurka        if (!mIsSmall) {
13520142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            super.scrollRight();
135331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
135431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1355138a04170d964da9cdec228e95b976875ae52481Karl Rosaen
13561262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    @Override
13571262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    public void onEnterScrollArea(int direction) {
13581262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        mInScrollArea = true;
13591262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        final int screen = getCurrentPage() + ((direction == DragController.SCROLL_LEFT) ? -1 : 1);
13601262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        if (0 <= screen && screen < getChildCount()) {
13611262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            ((CellLayout) getChildAt(screen)).setHover(true);
13621262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        }
13631262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy
13641262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        if (mDragTargetLayout != null) {
13651262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            mDragTargetLayout.onDragExit();
13661262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            mDragTargetLayout = null;
13671262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        }
13681262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    }
13691262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy
13701262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    @Override
13711262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    public void onExitScrollArea() {
13721262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        mInScrollArea = false;
13731262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        final int childCount = getChildCount();
13741262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        for (int i = 0; i < childCount; i++) {
13751262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy            ((CellLayout) getChildAt(i)).setHover(false);
13761262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy        }
13771262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy    }
13781262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy
137931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public Folder getFolderForTag(Object tag) {
1380dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenCount = getChildCount();
138131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        for (int screen = 0; screen < screenCount; screen++) {
138231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            CellLayout currentScreen = ((CellLayout) getChildAt(screen));
138331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int count = currentScreen.getChildCount();
138431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
138531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                View child = currentScreen.getChildAt(i);
138631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
138731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                if (lp.cellHSpan == 4 && lp.cellVSpan == 4 && child instanceof Folder) {
138831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    Folder f = (Folder) child;
1389aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                    if (f.getInfo() == tag && f.getInfo().opened) {
139031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                        return f;
139131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    }
139231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
139331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
139431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
139531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return null;
139631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
139731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
139831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    public View getViewForTag(Object tag) {
139931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        int screenCount = getChildCount();
140031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        for (int screen = 0; screen < screenCount; screen++) {
140131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            CellLayout currentScreen = ((CellLayout) getChildAt(screen));
140231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            int count = currentScreen.getChildCount();
140331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            for (int i = 0; i < count; i++) {
140431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                View child = currentScreen.getChildAt(i);
140531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                if (child.getTag() == tag) {
140631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                    return child;
140731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
140831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            }
140931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
141031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        return null;
141131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
141231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
141331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
141464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato    void removeItems(final ArrayList<ApplicationInfo> apps) {
1415dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenCount = getChildCount();
14165c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy        final PackageManager manager = getContext().getPackageManager();
1417629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy        final AppWidgetManager widgets = AppWidgetManager.getInstance(getContext());
1418574d20ec84551370987dde530c27ec493bdef564Romain Guy
141964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato        final HashSet<String> packageNames = new HashSet<String>();
142064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato        final int appCount = apps.size();
142164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato        for (int i = 0; i < appCount; i++) {
142264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato            packageNames.add(apps.get(i).componentName.getPackageName());
142364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato        }
142464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato
1425dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        for (int i = 0; i < screenCount; i++) {
142631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project            final CellLayout layout = (CellLayout) getChildAt(i);
1427629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy
1428629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy            // Avoid ANRs by treating each screen separately
1429629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy            post(new Runnable() {
1430629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                public void run() {
1431629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                    final ArrayList<View> childrenToRemove = new ArrayList<View>();
1432629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                    childrenToRemove.clear();
1433aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
1434629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                    int childCount = layout.getChildCount();
1435629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                    for (int j = 0; j < childCount; j++) {
1436629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        final View view = layout.getChildAt(j);
1437629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        Object tag = view.getTag();
1438aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
14390589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                        if (tag instanceof ShortcutInfo) {
14400589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                            final ShortcutInfo info = (ShortcutInfo) tag;
1441629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final Intent intent = info.intent;
1442629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final ComponentName name = intent.getComponent();
1443aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
144464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                            if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
144564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                for (String packageName: packageNames) {
144664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    if (packageName.equals(name.getPackageName())) {
144764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        LauncherModel.deleteItemFromDatabase(mLauncher, info);
144864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        childrenToRemove.add(view);
144964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    }
145064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                }
1451629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            }
1452629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        } else if (tag instanceof UserFolderInfo) {
1453629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final UserFolderInfo info = (UserFolderInfo) tag;
14540589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                            final ArrayList<ShortcutInfo> contents = info.contents;
14550589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                            final ArrayList<ShortcutInfo> toRemove = new ArrayList<ShortcutInfo>(1);
1456629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final int contentsCount = contents.size();
1457629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            boolean removedFromFolder = false;
1458aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
1459629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            for (int k = 0; k < contentsCount; k++) {
14600589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                                final ShortcutInfo appInfo = contents.get(k);
1461629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                final Intent intent = appInfo.intent;
1462629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                final ComponentName name = intent.getComponent();
1463aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
146464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                if (Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
146564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    for (String packageName: packageNames) {
146664e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        if (packageName.equals(name.getPackageName())) {
146764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                            toRemove.add(appInfo);
146873013bf94f49ffbacba2b8300f6a2dd4eeebbd13Brad Fitzpatrick                                            LauncherModel.deleteItemFromDatabase(mLauncher, appInfo);
146964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                            removedFromFolder = true;
147064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        }
147164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    }
1472629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                }
1473629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            }
1474aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
1475629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            contents.removeAll(toRemove);
1476629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            if (removedFromFolder) {
1477629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                final Folder folder = getOpenFolder();
1478aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                                if (folder != null)
1479aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                                    folder.notifyDataSetChanged();
1480629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            }
1481629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        } else if (tag instanceof LiveFolderInfo) {
1482629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final LiveFolderInfo info = (LiveFolderInfo) tag;
1483629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final Uri uri = info.uri;
1484629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final ProviderInfo providerInfo = manager.resolveContentProvider(
1485629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    uri.getAuthority(), 0);
1486629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy
1487f11079b11e98912ed56546eaa300efd06c6eb917Joe Onorato                            if (providerInfo != null) {
148864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                for (String packageName: packageNames) {
148964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    if (packageName.equals(providerInfo.packageName)) {
149064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        LauncherModel.deleteItemFromDatabase(mLauncher, info);
1491aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                                        childrenToRemove.add(view);
149264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    }
149364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                }
1494629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            }
1495629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        } else if (tag instanceof LauncherAppWidgetInfo) {
1496629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) tag;
1497629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            final AppWidgetProviderInfo provider =
1498629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                                    widgets.getAppWidgetInfo(info.appWidgetId);
1499e1cc6c3745c9ba721b6ab888d74c9d9e1d13ea6aDaniel Sandler                            if (provider != null) {
150064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                for (String packageName: packageNames) {
150164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    if (packageName.equals(provider.provider.getPackageName())) {
150264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        LauncherModel.deleteItemFromDatabase(mLauncher, info);
1503aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                                        childrenToRemove.add(view);
150464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                    }
150564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                }
1506629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            }
1507574d20ec84551370987dde530c27ec493bdef564Romain Guy                        }
1508574d20ec84551370987dde530c27ec493bdef564Romain Guy                    }
1509aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
1510629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                    childCount = childrenToRemove.size();
1511629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                    for (int j = 0; j < childCount; j++) {
1512629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        View child = childrenToRemove.get(j);
1513629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        layout.removeViewInLayout(child);
1514629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        if (child instanceof DropTarget) {
1515629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                            mDragController.removeDropTarget((DropTarget)child);
1516629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        }
1517574d20ec84551370987dde530c27ec493bdef564Romain Guy                    }
1518aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung
1519629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                    if (childCount > 0) {
1520629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        layout.requestLayout();
1521629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy                        layout.invalidate();
15225c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy                    }
152331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project                }
1524629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy            });
152531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project        }
152631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
1527f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
152864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato    void updateShortcuts(ArrayList<ApplicationInfo> apps) {
1529dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        final int screenCount = getChildCount();
1530dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka        for (int i = 0; i < screenCount; i++) {
1531f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            final CellLayout layout = (CellLayout) getChildAt(i);
1532f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            int childCount = layout.getChildCount();
1533f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            for (int j = 0; j < childCount; j++) {
1534f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                final View view = layout.getChildAt(j);
1535f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                Object tag = view.getTag();
15360589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                if (tag instanceof ShortcutInfo) {
15370589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato                    ShortcutInfo info = (ShortcutInfo)tag;
1538f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    // We need to check for ACTION_MAIN otherwise getComponent() might
1539f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    // return null for some shortcuts (for instance, for shortcuts to
1540f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    // web pages.)
1541f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    final Intent intent = info.intent;
1542f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    final ComponentName name = intent.getComponent();
1543f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
154464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                            Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
154564e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                        final int appCount = apps.size();
1546aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung                        for (int k = 0; k < appCount; k++) {
154764e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                            ApplicationInfo app = apps.get(k);
154864e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                            if (app.componentName.equals(name)) {
154964e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                info.setIcon(mIconCache.getIcon(info.intent));
155064e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                ((TextView)view).setCompoundDrawablesWithIntrinsicBounds(null,
155164e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        new FastBitmapDrawable(info.getIcon(mIconCache)),
155264e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                        null, null);
155364e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                                }
155464e6be78dc72e1a89fe8fb95c502586f9260df28Joe Onorato                        }
1555f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                    }
1556f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project                }
1557f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project            }
1558f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project        }
1559f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project    }
1560f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Project
156114f122bf847e50a3e7730ccbe57abc25d086a01bJoe Onorato    void moveToDefaultScreen(boolean animate) {
1562c45b16862918a0c6c253bba12032165b030565afJoe Onorato        if (animate) {
15634cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka            if (mIsSmall) {
15640142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                unshrink(mDefaultPage);
15654cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka            } else {
15660142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka                snapToPage(mDefaultPage);
15674cb3724a2c1e5f278e1531d643accc40fcd8e219Michael Jurka            }
1568c45b16862918a0c6c253bba12032165b030565afJoe Onorato        } else {
15690142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka            setCurrentPage(mDefaultPage);
1570c45b16862918a0c6c253bba12032165b030565afJoe Onorato        }
15710142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        getChildAt(mDefaultPage).requestFocus();
157231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
157331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
15748a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy    void setIndicators(Drawable previous, Drawable next) {
15758a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy        mPreviousIndicator = previous;
15768a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy        mNextIndicator = next;
15770142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        previous.setLevel(mCurrentPage);
15780142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka        next.setLevel(mCurrentPage);
15798a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy    }
15808a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy
15810142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    @Override
15820142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    public void syncPages() {
15830142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    }
158431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project
15850142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    @Override
15860142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka    public void syncPageItems(int page) {
158731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project    }
15880142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka
158931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project}
1590