Adding single/multi selection mode to AllAppsPagedView (action bar disabled).

Also adding check to prevent scrolling mode from continuing on touch down.

Change-Id: I744f2c1f6bc659219145b52b15a7ea176853ec7c
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index 5052a59..8e0203b 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -19,7 +19,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
-
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -27,6 +26,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.view.ActionMode;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
@@ -36,6 +37,7 @@
 import android.view.animation.Animation;
 import android.view.animation.Animation.AnimationListener;
 import android.view.animation.AnimationUtils;
+import android.widget.Checkable;
 import android.widget.Scroller;
 
 import com.android.launcher.R;
@@ -51,6 +53,7 @@
     // the min drag distance for a fling to register, to prevent random page shifts
     private static final int MIN_LENGTH_FOR_FLING = 50;
 
+    private static final int PAGE_SNAP_ANIMATION_DURATION = 1000;
     protected static final float NANOTIME_DIV = 1000000000.0f;
 
     // the velocity at which a fling gesture will cause us to snap to the next page
@@ -96,6 +99,14 @@
     private ArrayList<Boolean> mDirtyPageContent;
     private boolean mDirtyPageAlpha;
 
+    // choice modes
+    protected static final int CHOICE_MODE_NONE = 0;
+    protected static final int CHOICE_MODE_SINGLE = 1;
+    // Multiple selection mode is not supported by all Launcher actions atm
+    protected static final int CHOICE_MODE_MULTIPLE = 2;
+    private int mChoiceMode;
+    private ActionMode mActionMode;
+
     protected PagedViewIconCache mPageViewIconCache;
 
     // If true, syncPages and syncPageItems will be called to refresh pages
@@ -153,6 +164,7 @@
 
     public PagedView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        mChoiceMode = CHOICE_MODE_NONE;
 
         setHapticFeedbackEnabled(false);
         init();
@@ -530,7 +542,14 @@
                  * otherwise don't.  mScroller.isFinished should be false when
                  * being flinged.
                  */
-                mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
+                final int xDist = (mScroller.getFinalX() - mScroller.getCurrX());
+                final boolean finishedScrolling = (mScroller.isFinished() || xDist < mTouchSlop);
+                if (finishedScrolling) {
+                    mTouchState = TOUCH_STATE_REST;
+                    mScroller.abortAnimation();
+                } else {
+                    mTouchState = TOUCH_STATE_SCROLLING;
+                }
 
                 // check if this can be the beginning of a tap on the side of the pages
                 // to scroll the current page
@@ -819,7 +838,7 @@
                 minDistanceFromScreenCenterIndex = i;
             }
         }
-        snapToPage(minDistanceFromScreenCenterIndex, 1000);
+        snapToPage(minDistanceFromScreenCenterIndex, PAGE_SNAP_ANIMATION_DURATION);
     }
 
     protected void snapToPageWithVelocity(int whichPage, int velocity) {
@@ -829,7 +848,7 @@
     }
 
     protected void snapToPage(int whichPage) {
-        snapToPage(whichPage, 1000);
+        snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
     }
 
     protected void snapToPage(int whichPage, int duration) {
@@ -982,6 +1001,50 @@
         }
     }
 
+    protected void startChoiceMode(int mode, ActionMode.Callback callback) {
+        // StartActionMode may call through toendChoiceMode, so we should do this first
+        mActionMode = startActionMode(callback);
+        mChoiceMode = mode;
+    }
+
+    protected void endChoiceMode() {
+        if (!isChoiceMode(CHOICE_MODE_NONE)) {
+            mActionMode.finish();
+            mActionMode = null;
+            mChoiceMode = CHOICE_MODE_NONE;
+            resetCheckedGrandchildren();
+        }
+    }
+
+    protected boolean isChoiceMode(int mode) {
+        return mChoiceMode == mode;
+    }
+
+    protected ArrayList<Checkable> getCheckedGrandchildren() {
+        ArrayList<Checkable> checked = new ArrayList<Checkable>();
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; ++i) {
+            final PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(i);
+            final int grandChildCount = layout.getChildCount();
+            for (int j = 0; j < grandChildCount; ++j) {
+                final View v = layout.getChildAt(j);
+                if (v instanceof Checkable) {
+                    checked.add((Checkable) v);
+                }
+            }
+        }
+        return checked;
+    }
+
+    protected void resetCheckedGrandchildren() {
+        // loop through children, and set all of their children to _not_ be checked
+        final ArrayList<Checkable> checked = getCheckedGrandchildren();
+        for (int i = 0; i < checked.size(); ++i) {
+            final Checkable c = checked.get(i);
+            c.setChecked(false);
+        }
+    }
+
     /**
      * This method is called ONLY to synchronize the number of pages that the paged view has.
      * To actually fill the pages with information, implement syncPageItems() below.  It is