Merge "Initial Changes for Dynamic Grid" into jb-ub-gel-agar
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index bf4748c..1dcc5dd 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -89,6 +89,7 @@
     <declare-styleable name="HolographicLinearLayout">
         <!-- The source view to generate and apply the drawable states to/from -->
         <attr name="sourceImageViewId" format="integer" />
+        <attr name="stateHotwordOn" format="boolean" />
     </declare-styleable>
 
     <!-- PagedView specific attributes. These attributes are used to customize
diff --git a/src/com/android/launcher3/HolographicImageView.java b/src/com/android/launcher3/HolographicImageView.java
index 0ad82a7..ce50db1 100644
--- a/src/com/android/launcher3/HolographicImageView.java
+++ b/src/com/android/launcher3/HolographicImageView.java
@@ -17,13 +17,23 @@
 package com.android.launcher3;
 
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.StateListDrawable;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.view.View.OnTouchListener;
 import android.widget.ImageView;
 
 public class HolographicImageView extends ImageView {
 
     private final HolographicViewHelper mHolographicHelper;
+    private boolean mHotwordOn;
+    private boolean mIsPressed;
+    private boolean mIsFocused;
 
     public HolographicImageView(Context context) {
         this(context, null);
@@ -37,6 +47,31 @@
         super(context, attrs, defStyle);
 
         mHolographicHelper = new HolographicViewHelper(context);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
+                defStyle, 0);
+        mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
+        a.recycle();
+
+        setOnTouchListener(new OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (isPressed() != mIsPressed) {
+                    mIsPressed = isPressed();
+                    refreshDrawableState();
+                }
+                return false;
+            }
+        });
+
+        setOnFocusChangeListener(new OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                if (isFocused() != mIsFocused) {
+                    mIsFocused = isFocused();
+                    refreshDrawableState();
+                }
+            }
+        });
     }
 
     void invalidatePressedFocusedStates() {
@@ -44,6 +79,19 @@
     }
 
     @Override
+    protected void drawableStateChanged() {
+        super.drawableStateChanged();
+
+        mHolographicHelper.generatePressedFocusedStates(this);
+        Drawable d = getDrawable();
+        if (d instanceof StateListDrawable) {
+            StateListDrawable sld = (StateListDrawable) d;
+            sld.setState(getDrawableState());
+            sld.invalidateSelf();
+        }
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
 
@@ -51,4 +99,25 @@
         // measure/layout
         mHolographicHelper.generatePressedFocusedStates(this);
     }
+
+    private boolean isHotwordOn() {
+        return mHotwordOn;
+    }
+
+    public void setHotwordState(boolean on) {
+        if (on == mHotwordOn) {
+            return;
+        }
+        mHotwordOn = on;
+        refreshDrawableState();
+    }
+
+    @Override
+    public int[] onCreateDrawableState(int extraSpace) {
+        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+        if (isHotwordOn()) {
+            mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
+        }
+        return drawableState;
+    }
 }
diff --git a/src/com/android/launcher3/HolographicLinearLayout.java b/src/com/android/launcher3/HolographicLinearLayout.java
index 73d4c3a..cdf4381 100644
--- a/src/com/android/launcher3/HolographicLinearLayout.java
+++ b/src/com/android/launcher3/HolographicLinearLayout.java
@@ -22,17 +22,22 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnFocusChangeListener;
+import android.view.View.OnTouchListener;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
-import com.android.launcher3.R;
-
 public class HolographicLinearLayout extends LinearLayout {
-
     private final HolographicViewHelper mHolographicHelper;
     private ImageView mImageView;
     private int mImageViewId;
 
+    private boolean mHotwordOn;
+    private boolean mIsPressed;
+    private boolean mIsFocused;
+
     public HolographicLinearLayout(Context context) {
         this(context, null);
     }
@@ -47,10 +52,33 @@
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
                 defStyle, 0);
         mImageViewId = a.getResourceId(R.styleable.HolographicLinearLayout_sourceImageViewId, -1);
+        mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
         a.recycle();
 
+
         setWillNotDraw(false);
         mHolographicHelper = new HolographicViewHelper(context);
+
+        setOnTouchListener(new OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (isPressed() != mIsPressed) {
+                    mIsPressed = isPressed();
+                    refreshDrawableState();
+                }
+                return false;
+            }
+        });
+
+        setOnFocusChangeListener(new OnFocusChangeListener() {
+            @Override
+            public void onFocusChange(View v, boolean hasFocus) {
+                if (isFocused() != mIsFocused) {
+                    mIsFocused = isFocused();
+                    refreshDrawableState();
+                }
+            }
+        });
     }
 
     @Override
@@ -58,10 +86,12 @@
         super.drawableStateChanged();
 
         if (mImageView != null) {
+            mHolographicHelper.generatePressedFocusedStates(mImageView);
             Drawable d = mImageView.getDrawable();
             if (d instanceof StateListDrawable) {
                 StateListDrawable sld = (StateListDrawable) d;
                 sld.setState(getDrawableState());
+                sld.invalidateSelf();
             }
         }
     }
@@ -82,4 +112,25 @@
         }
         mHolographicHelper.generatePressedFocusedStates(mImageView);
     }
+
+    private boolean isHotwordOn() {
+        return mHotwordOn;
+    }
+
+    public void setHotwordState(boolean on) {
+        if (on == mHotwordOn) {
+            return;
+        }
+        mHotwordOn = on;
+        refreshDrawableState();
+    }
+
+    @Override
+    public int[] onCreateDrawableState(int extraSpace) {
+        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+        if (isHotwordOn()) {
+            mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
+        }
+        return drawableState;
+    }
 }
diff --git a/src/com/android/launcher3/HolographicViewHelper.java b/src/com/android/launcher3/HolographicViewHelper.java
index 9d3ad70..7ef0355 100644
--- a/src/com/android/launcher3/HolographicViewHelper.java
+++ b/src/com/android/launcher3/HolographicViewHelper.java
@@ -30,11 +30,12 @@
     private final Canvas mTempCanvas = new Canvas();
 
     private boolean mStatesUpdated;
-    private int mHighlightColor;
+    private int mHighlightColor, mHotwordColor;
 
     public HolographicViewHelper(Context context) {
         Resources res = context.getResources();
         mHighlightColor = res.getColor(android.R.color.holo_blue_light);
+        mHotwordColor = res.getColor(android.R.color.holo_green_light);
     }
 
     /**
@@ -44,13 +45,17 @@
         if (!mStatesUpdated && v != null) {
             mStatesUpdated = true;
             Bitmap original = createOriginalImage(v, mTempCanvas);
-            Bitmap outline = createPressImage(v, mTempCanvas);
+            Bitmap outline = createImageWithOverlay(v, mTempCanvas, mHighlightColor);
+            Bitmap hotword = createImageWithOverlay(v, mTempCanvas, mHotwordColor);
             FastBitmapDrawable originalD = new FastBitmapDrawable(original);
             FastBitmapDrawable outlineD = new FastBitmapDrawable(outline);
+            FastBitmapDrawable hotwordD = new FastBitmapDrawable(hotword);
 
             StateListDrawable states = new StateListDrawable();
+
             states.addState(new int[] {android.R.attr.state_pressed}, outlineD);
             states.addState(new int[] {android.R.attr.state_focused}, outlineD);
+            states.addState(new int[] {R.attr.stateHotwordOn}, hotwordD);
             states.addState(new int[] {}, originalD);
             v.setImageDrawable(states);
         }
@@ -76,7 +81,7 @@
 
         canvas.setBitmap(b);
         canvas.save();
-            d.draw(canvas);
+        d.draw(canvas);
         canvas.restore();
         canvas.setBitmap(null);
 
@@ -87,16 +92,16 @@
      * Creates a new press state image which is the old image with a blue overlay.
      * Responsibility for the bitmap is transferred to the caller.
      */
-    private Bitmap createPressImage(ImageView v, Canvas canvas) {
+    private Bitmap createImageWithOverlay(ImageView v, Canvas canvas, int color) {
         final Drawable d = v.getDrawable();
         final Bitmap b = Bitmap.createBitmap(
                 d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
 
         canvas.setBitmap(b);
         canvas.save();
-            d.draw(canvas);
+        d.draw(canvas);
         canvas.restore();
-        canvas.drawColor(mHighlightColor, PorterDuff.Mode.SRC_IN);
+        canvas.drawColor(color, PorterDuff.Mode.SRC_IN);
         canvas.setBitmap(null);
 
         return b;