Cleaning up widget resizing code

Change-Id: Ib4c0de0080f0b69f873fd88016f23c319a13c6ff
diff --git a/src/com/android/launcher2/AppWidgetResizeFrame.java b/src/com/android/launcher2/AppWidgetResizeFrame.java
index 40347ad..5f725b7 100644
--- a/src/com/android/launcher2/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher2/AppWidgetResizeFrame.java
@@ -20,7 +20,7 @@
     private CellLayout mCellLayout;
     private ImageView mLeftHandle;
     private ImageView mRightHandle;
-    private ImageView mTopHandle; 
+    private ImageView mTopHandle;
     private ImageView mBottomHandle;
 
     private boolean mLeftBorderActive;
@@ -40,6 +40,7 @@
     private int mMinVSpan;
     private int mDeltaX;
     private int mDeltaY;
+
     private int mBackgroundPadding;
     private int mTouchTargetWidth;
 
@@ -49,6 +50,11 @@
     final int BACKGROUND_PADDING = 24;
     final float DIMMED_HANDLE_ALPHA = 0.3f;
 
+    public static final int LEFT = 0;
+    public static final int TOP = 1;
+    public static final int RIGHT = 2;
+    public static final int BOTTOM = 3;
+
     public AppWidgetResizeFrame(Context context, ItemInfo itemInfo, 
             LauncherAppWidgetHostView widgetView, CellLayout cellLayout) {
 
@@ -134,6 +140,10 @@
         return anyBordersActive;
     }
 
+    /**
+     *  Here we bound the deltas such that the frame cannot be stretched beyond the extents
+     *  of the CellLayout, and such that the frame's borders can't cross.
+     */
     public void updateDeltas(int deltaX, int deltaY) {
         if (mLeftBorderActive) {
             mDeltaX = Math.max(-mBaselineX, deltaX); 
@@ -152,6 +162,9 @@
         }
     }
 
+    /**
+     *  Based on the deltas, we resize the frame, and, if needed, we resize the widget.
+     */
     public void visualizeResizeForDelta(int deltaX, int deltaY) {
         updateDeltas(deltaX, deltaY);
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
@@ -173,6 +186,9 @@
         requestLayout();
     }
 
+    /**
+     *  Based on the current deltas, we determine if and how to resize the widget.
+     */
     private void resizeWidgetIfNeeded() {
         int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
         int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();
@@ -189,28 +205,31 @@
         mCellLayout.markCellsAsUnoccupiedForView(mWidgetView);
 
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams();
+
+        // For each border, we bound the resizing based on the minimum width, and the maximum
+        // expandability.
         if (mLeftBorderActive) {
-            cellXInc = Math.max(-mExpandability[0], hSpanInc);
+            cellXInc = Math.max(-mExpandability[LEFT], hSpanInc);
             cellXInc = Math.min(lp.cellHSpan - mMinHSpan, cellXInc);
             hSpanInc *= -1;
-            hSpanInc = Math.min(mExpandability[0], hSpanInc);
+            hSpanInc = Math.min(mExpandability[LEFT], hSpanInc);
             hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
             mRunningHInc -= hSpanInc;
         } else if (mRightBorderActive) {
-            hSpanInc = Math.min(mExpandability[2], hSpanInc);
+            hSpanInc = Math.min(mExpandability[RIGHT], hSpanInc);
             hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
             mRunningHInc += hSpanInc;
         }
 
         if (mTopBorderActive) {
-            cellYInc = Math.max(-mExpandability[1], vSpanInc);
+            cellYInc = Math.max(-mExpandability[TOP], vSpanInc);
             cellYInc = Math.min(lp.cellVSpan - mMinVSpan, cellYInc);
             vSpanInc *= -1;
-            vSpanInc = Math.min(mExpandability[1], vSpanInc);
+            vSpanInc = Math.min(mExpandability[TOP], vSpanInc);
             vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
             mRunningVInc -= vSpanInc;
         } else if (mBottomBorderActive) {
-            vSpanInc = Math.min(mExpandability[3], vSpanInc);
+            vSpanInc = Math.min(mExpandability[BOTTOM], vSpanInc);
             vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
             mRunningVInc += vSpanInc;
         }
@@ -226,12 +245,17 @@
             lp.cellY += cellYInc;
         }
 
+        // Update the expandability array, as we have changed the widget's size.
         mCellLayout.getExpandabilityArrayForView(mWidgetView, mExpandability);
 
         // Update the cells occupied by this widget
         mCellLayout.markCellsAsOccupiedForView(mWidgetView);
     }
 
+    /**
+     * This is the final step of the resize. Here we save the new widget size and position
+     * to LauncherModel and animate the resize frame.
+     */
     public void commitResizeForDelta(int deltaX, int deltaY) {
         visualizeResizeForDelta(deltaX, deltaY);
 
@@ -277,7 +301,8 @@
             requestLayout();
         } else {
             PropertyValuesHolder width = PropertyValuesHolder.ofInt("width", lp.width, newWidth);
-            PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", lp.height, newHeight);
+            PropertyValuesHolder height = PropertyValuesHolder.ofInt("height", lp.height,
+                    newHeight);
             PropertyValuesHolder x = PropertyValuesHolder.ofInt("x", lp.x, newX);
             PropertyValuesHolder y = PropertyValuesHolder.ofInt("y", lp.y, newY);
             ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(lp, width, height, x, y);
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index a2a539e..0fb87ba 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -589,7 +589,8 @@
             final View child = mChildren.getChildAt(i);
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
 
-            if ((child.getVisibility() == VISIBLE || child.getAnimation() != null) && lp.isLockedToGrid) {
+            if ((child.getVisibility() == VISIBLE || child.getAnimation() != null) &&
+                    lp.isLockedToGrid) {
                 child.getHitRect(frame);
                 if (frame.contains(x, y)) {
                     cellInfo.cell = child;
@@ -1340,53 +1341,54 @@
         }
     }
 
+    /**
+     * Given a view, determines how much that view can be expanded in all directions, in terms of
+     * whether or not there are other items occupying adjacent cells. Used by the
+     * AppWidgetResizeFrame to determine how the widget can be resized.
+     */
     public void getExpandabilityArrayForView(View view, int[] expandability) {
-        final LayoutParams lp = (LayoutParams) view.getLayoutParams();        
+        final LayoutParams lp = (LayoutParams) view.getLayoutParams();
         boolean flag;
 
-        // Left
-        expandability[0] = 0;
+        expandability[AppWidgetResizeFrame.LEFT] = 0;
         for (int x = lp.cellX - 1; x >= 0; x--) {
             flag = false;
             for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan; y++) {
                 if (mOccupied[x][y]) flag = true;
             }
             if (flag) break;
-            expandability[0]++;
+            expandability[AppWidgetResizeFrame.LEFT]++;
         }
 
-        // Top
-        expandability[1] = 0;
+        expandability[AppWidgetResizeFrame.TOP] = 0;
         for (int y = lp.cellY - 1; y >= 0; y--) {
             flag = false;
             for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan; x++) {
                 if (mOccupied[x][y]) flag = true;
             }
             if (flag) break;
-            expandability[1]++;
-        } 
+            expandability[AppWidgetResizeFrame.TOP]++;
+        }
 
-        // Right   
-        expandability[2] = 0;
+        expandability[AppWidgetResizeFrame.RIGHT] = 0;
         for (int x = lp.cellX + lp.cellHSpan; x < mCountX; x++) {
             flag = false;
             for (int y = lp.cellY; y < lp.cellY + lp.cellVSpan; y++) {
                 if (mOccupied[x][y]) flag = true;
             }
             if (flag) break;
-            expandability[2]++;
-        } 
+            expandability[AppWidgetResizeFrame.RIGHT]++;
+        }
 
-        // Bottom
-        expandability[3] = 0;
+        expandability[AppWidgetResizeFrame.BOTTOM] = 0;
         for (int y = lp.cellY + lp.cellVSpan; y < mCountY; y++) {
             flag = false;
             for (int x = lp.cellX; x < lp.cellX + lp.cellHSpan; x++) {
                 if (mOccupied[x][y]) flag = true;
             }
             if (flag) break;
-            expandability[3]++;
-        } 
+            expandability[AppWidgetResizeFrame.BOTTOM]++;
+        }
     }
 
     public void onMove(View view, int newCellX, int newCellY) {
@@ -1466,6 +1468,10 @@
         @ViewDebug.ExportedProperty
         public int cellVSpan;
 
+        /**
+         * Indicates whether the item will set its x, y, width and height parameters freely,
+         * or whether these will be computed based on cellX, cellY, cellHSpan and cellVSpan.
+         */
         public boolean isLockedToGrid = true;
 
         /**
@@ -1531,12 +1537,11 @@
                 final int myCellVSpan = cellVSpan;
                 final int myCellX = cellX;
                 final int myCellY = cellY;
-    
+
                 width = myCellHSpan * cellWidth + ((myCellHSpan - 1) * widthGap) -
                         leftMargin - rightMargin;
                 height = myCellVSpan * cellHeight + ((myCellVSpan - 1) * heightGap) -
                         topMargin - bottomMargin;
-    
                 x = hStartPadding + myCellX * (cellWidth + widthGap) + leftMargin;
                 y = vStartPadding + myCellY * (cellHeight + heightGap) + topMargin;
             }
diff --git a/src/com/android/launcher2/CellLayoutChildren.java b/src/com/android/launcher2/CellLayoutChildren.java
index 9a0d772..04996f3 100644
--- a/src/com/android/launcher2/CellLayoutChildren.java
+++ b/src/com/android/launcher2/CellLayoutChildren.java
@@ -43,6 +43,12 @@
     private int mWidthGap;
     private int mHeightGap;
 
+    // Variables relating to resizing widgets
+    private final ArrayList<AppWidgetResizeFrame> mResizeFrames =
+            new ArrayList<AppWidgetResizeFrame>();
+    private AppWidgetResizeFrame mCurrentResizeFrame;
+    private int mXDown, mYDown;
+
     public CellLayoutChildren(Context context) {
         super(context);
         mWallpaperManager = WallpaperManager.getInstance(context);
@@ -171,11 +177,6 @@
         super.setChildrenDrawnWithCacheEnabled(enabled);
     }
 
-    private final ArrayList<AppWidgetResizeFrame> mResizeFrames = new  ArrayList<AppWidgetResizeFrame>();
-    private AppWidgetResizeFrame mCurrentResizeFrame;
-    private int mXDown, mYDown;
-    private boolean mIsWidgetBeingResized;
-
     public void clearAllResizeFrames() {
         for (AppWidgetResizeFrame frame: mResizeFrames) {
             removeView(frame);
@@ -183,32 +184,41 @@
         mResizeFrames.clear();
     }
 
-    public boolean isWidgetBeingResized() {
-        return mIsWidgetBeingResized;
+    public boolean hasResizeFrames() {
+        return mResizeFrames.size() > 0;
     }
 
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
+    public boolean isWidgetBeingResized() {
+        return mCurrentResizeFrame != null;
+    }
+
+    private boolean handleTouchDown(MotionEvent ev) {
         Rect hitRect = new Rect();
 
         int x = (int) ev.getX();
         int y = (int) ev.getY();
 
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            for (AppWidgetResizeFrame child: mResizeFrames) {
-                child.getHitRect(hitRect);
-                if (hitRect.contains(x, y)) {
-                    if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
-                        mCurrentResizeFrame = child;
-                        mIsWidgetBeingResized = true;
-                        mXDown = x;
-                        mYDown = y;
-                        requestDisallowInterceptTouchEvent(true);
-                        return true;
-                    }
+        for (AppWidgetResizeFrame child: mResizeFrames) {
+            child.getHitRect(hitRect);
+            if (hitRect.contains(x, y)) {
+                if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
+                    mCurrentResizeFrame = child;
+                    mXDown = x;
+                    mYDown = y;
+                    requestDisallowInterceptTouchEvent(true);
+                    return true;
                 }
             }
-            mCurrentResizeFrame = null;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            if (handleTouchDown(ev)) {
+                return true;
+            }
         }
         return false;
     }
@@ -216,47 +226,36 @@
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         boolean handled = false;
-        Rect hitRect = new Rect();
         int action = ev.getAction();
 
         int x = (int) ev.getX();
         int y = (int) ev.getY();
 
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            for (AppWidgetResizeFrame child: mResizeFrames) {
-                child.getHitRect(hitRect);
-                if (hitRect.contains(x, y)) {
-                    if (child.beginResizeIfPointInRegion(x - child.getLeft(), y - child.getTop())) {
-                        mCurrentResizeFrame = child;
-                        mIsWidgetBeingResized = true;
-                        mXDown = x;
-                        mYDown = y;
-                        requestDisallowInterceptTouchEvent(true);
-                        return true;
-                    }
+            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+                if (handleTouchDown(ev)) {
+                    return true;
                 }
             }
-            mCurrentResizeFrame = null;
         }
 
-        // TODO: Need to handle ACTION_POINTER_UP / multi-touch
         if (mCurrentResizeFrame != null) {
+            handled = true;
             switch (action) {
                 case MotionEvent.ACTION_MOVE:
                     mCurrentResizeFrame.visualizeResizeForDelta(x - mXDown, y - mYDown);
                     break;
                 case MotionEvent.ACTION_CANCEL:
-                case MotionEvent.ACTION_UP: {
+                case MotionEvent.ACTION_UP:
                     mCurrentResizeFrame.commitResizeForDelta(x - mXDown, y - mYDown);
-                    mIsWidgetBeingResized = false;
-                    handled = true;
-                }
+                    mCurrentResizeFrame = null;
             }
         }
         return handled;
     }
 
-    public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget, CellLayout cellLayout) {
+    public void addResizeFrame(ItemInfo itemInfo, LauncherAppWidgetHostView widget,
+            CellLayout cellLayout) {
         AppWidgetResizeFrame resizeFrame = new AppWidgetResizeFrame(getContext(),
                 itemInfo, widget, cellLayout);
 
diff --git a/src/com/android/launcher2/DragLayer.java b/src/com/android/launcher2/DragLayer.java
index 1912f81..37bbb05 100644
--- a/src/com/android/launcher2/DragLayer.java
+++ b/src/com/android/launcher2/DragLayer.java
@@ -58,17 +58,21 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // Here we need to detect if any touch event has occured which doesn't result
-        // in resizing a widget. In this case, we dismiss any visible resize frames.
-        post(new Runnable() {
-            public void run() {
-                Workspace w = (Workspace) findViewById(R.id.workspace);
-                CellLayout currentPage = (CellLayout) w.getChildAt(w.getCurrentPage());
-                if (!currentPage.getChildrenLayout().isWidgetBeingResized()) {
-                    currentPage.getChildrenLayout().clearAllResizeFrames();
-                }                
-            }
-        });
+        // If the current CellLayoutChildren has a resize frame, we need to detect if any touch
+        // event has occurred which doesn't result in resizing a widget. In this case, we
+        // dismiss any visible resize frames.
+        final Workspace w = (Workspace) findViewById(R.id.workspace);
+        final CellLayout currentPage = (CellLayout) w.getChildAt(w.getCurrentPage());
+
+        if (currentPage.getChildrenLayout().hasResizeFrames()) {
+            post(new Runnable() {
+                public void run() {
+                    if (!currentPage.getChildrenLayout().isWidgetBeingResized()) {
+                        currentPage.getChildrenLayout().clearAllResizeFrames();
+                    }
+                }
+            });
+        }
         return mDragController.onInterceptTouchEvent(ev);
     }
 
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 12f5737..c098749 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -177,9 +177,9 @@
     }
 
     /**
-     * Resize an item in the DB to a new <spanX, spanY>
+     * Resize an item in the DB to a new <spanX, spanY, cellX, cellY>
      */
-    static void resizeItemInDatabase(Context context, ItemInfo item, int cellX, int cellY, 
+    static void resizeItemInDatabase(Context context, ItemInfo item, int cellX, int cellY,
             int spanX, int spanY) {
         item.spanX = spanX;
         item.spanY = spanY;