Merge "Preserve spacing for icons in menus"
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 9c06d69..80f68ac 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -544,6 +544,17 @@
             }
 
             setCallback(mPopupPresenterCallback);
+
+            boolean preserveIconSpacing = false;
+            final int count = subMenu.size();
+            for (int i = 0; i < count; i++) {
+                MenuItem childItem = subMenu.getItem(i);
+                if (childItem.isVisible() && childItem.getIcon() != null) {
+                    preserveIconSpacing = true;
+                    break;
+                }
+            }
+            setForceShowIcon(preserveIconSpacing);
         }
 
         @Override
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index 0c3c605..a1e16d4 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -22,6 +22,7 @@
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
 import android.widget.ImageView;
@@ -50,6 +51,8 @@
     
     private LayoutInflater mInflater;
 
+    private boolean mForceShowIcon;
+
     public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs);
     
@@ -99,6 +102,10 @@
         setEnabled(itemData.isEnabled());
     }
 
+    public void setForceShowIcon(boolean forceShow) {
+        mPreserveIconSpacing = mForceShowIcon = forceShow;
+    }
+
     public void setTitle(CharSequence title) {
         if (title != null) {
             mTitleView.setText(title);
@@ -189,12 +196,12 @@
     }
     
     public void setIcon(Drawable icon) {
-        final boolean showIcon = mItemData.shouldShowIcon();
+        final boolean showIcon = mItemData.shouldShowIcon() || mForceShowIcon;
         if (!showIcon && !mPreserveIconSpacing) {
             return;
         }
         
-        if (mIconView == null && icon == null) {
+        if (mIconView == null && icon == null && !mPreserveIconSpacing) {
             return;
         }
         
@@ -213,6 +220,19 @@
         }
     }
     
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (mIconView != null && mPreserveIconSpacing) {
+            // Enforce minimum icon spacing
+            ViewGroup.LayoutParams lp = getLayoutParams();
+            LayoutParams iconLp = (LayoutParams) mIconView.getLayoutParams();
+            if (lp.height > 0 && iconLp.width <= 0) {
+                iconLp.width = lp.height;
+            }
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
     private void insertIconView() {
         LayoutInflater inflater = getInflater();
         mIconView = (ImageView) inflater.inflate(com.android.internal.R.layout.list_menu_item_icon,
@@ -241,7 +261,7 @@
     }
 
     public boolean showsIcon() {
-        return false;
+        return mForceShowIcon;
     }
     
     private LayoutInflater getInflater() {
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 4ecc828..6265618 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -19,15 +19,16 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Parcelable;
-import android.util.DisplayMetrics;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
 import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
 import android.widget.PopupWindow;
@@ -58,6 +59,10 @@
 
     private Callback mPresenterCallback;
 
+    boolean mForceShowIcon;
+
+    private ViewGroup mMeasureParent;
+
     public MenuPopupHelper(Context context, MenuBuilder menu) {
         this(context, menu, null, false);
     }
@@ -86,6 +91,10 @@
         mAnchorView = anchor;
     }
 
+    public void setForceShowIcon(boolean forceShow) {
+        mForceShowIcon = forceShow;
+    }
+
     public void show() {
         if (!tryShow()) {
             throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
@@ -170,7 +179,10 @@
                 itemType = positionType;
                 itemView = null;
             }
-            itemView = adapter.getView(i, itemView, null);
+            if (mMeasureParent == null) {
+                mMeasureParent = new FrameLayout(mContext);
+            }
+            itemView = adapter.getView(i, itemView, mMeasureParent);
             itemView.measure(widthMeasureSpec, heightMeasureSpec);
             width = Math.max(width, itemView.getMeasuredWidth());
         }
@@ -228,6 +240,18 @@
         if (subMenu.hasVisibleItems()) {
             MenuPopupHelper subPopup = new MenuPopupHelper(mContext, subMenu, mAnchorView, false);
             subPopup.setCallback(mPresenterCallback);
+
+            boolean preserveIconSpacing = false;
+            final int count = subMenu.size();
+            for (int i = 0; i < count; i++) {
+                MenuItem childItem = subMenu.getItem(i);
+                if (childItem.isVisible() && childItem.getIcon() != null) {
+                    preserveIconSpacing = true;
+                    break;
+                }
+            }
+            subPopup.setForceShowIcon(preserveIconSpacing);
+
             if (subPopup.tryShow()) {
                 if (mPresenterCallback != null) {
                     mPresenterCallback.onOpenSubMenu(subMenu);
@@ -293,6 +317,9 @@
             }
 
             MenuView.ItemView itemView = (MenuView.ItemView) convertView;
+            if (mForceShowIcon) {
+                ((ListMenuItemView) convertView).setForceShowIcon(true);
+            }
             itemView.initialize(getItem(position), 0);
             return convertView;
         }
diff --git a/core/res/res/layout/list_menu_item_icon.xml b/core/res/res/layout/list_menu_item_icon.xml
index 6ff14dd..a885211 100644
--- a/core/res/res/layout/list_menu_item_icon.xml
+++ b/core/res/res/layout/list_menu_item_icon.xml
@@ -19,6 +19,8 @@
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="center_vertical"
-    android:layout_marginRight="8dip"
+    android:layout_marginLeft="8dip"
+    android:layout_marginRight="-8dip"
+    android:scaleType="center"
     android:duplicateParentState="true" />
 
diff --git a/core/res/res/layout/popup_menu_item_layout.xml b/core/res/res/layout/popup_menu_item_layout.xml
index fef017d..1a12c01 100644
--- a/core/res/res/layout/popup_menu_item_layout.xml
+++ b/core/res/res/layout/popup_menu_item_layout.xml
@@ -18,7 +18,6 @@
     android:layout_width="match_parent"
     android:layout_height="?android:attr/dropdownListPreferredItemHeight"
     android:minWidth="196dip"
-    android:paddingLeft="16dip"
     android:paddingRight="16dip">
     
     <!-- Icon will be inserted here. -->
@@ -29,6 +28,7 @@
         android:layout_weight="1"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
+        android:layout_marginLeft="16dip"
         android:duplicateParentState="true">
         
         <TextView