Loading core/java/android/widget/ActionMenuPresenter.java +26 −20 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter private OpenOverflowRunnable mPostedOpenRunnable; private ActionMenuPopupCallback mPopupCallback; private final boolean mShowCascadingMenus; final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); int mOpenSubMenuId; Loading Loading @@ -126,6 +128,9 @@ public class ActionMenuPresenter extends BaseMenuPresenter public ActionMenuPresenter(Context context) { super(context, com.android.internal.R.layout.action_menu_layout, com.android.internal.R.layout.action_menu_item_layout); mShowCascadingMenus = context.getResources().getBoolean( com.android.internal.R.bool.config_enableCascadingSubmenus); } @Override Loading Loading @@ -500,14 +505,29 @@ public class ActionMenuPresenter extends BaseMenuPresenter } View anchor = findViewForItem(topSubMenu.getItem()); if (anchor == null) { if (mOverflowButton == null) return false; anchor = mOverflowButton; // This means the submenu was opened from an overflow menu item, indicating the // MenuPopupHelper will handle opening the submenu via its MenuPopup. Return false to // ensure that the MenuPopup acts as presenter for the submenu, and acts on its // responsibility to display the new submenu. return false; } mOpenSubMenuId = subMenu.getItem().getItemId(); mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); mActionButtonPopup.setAnchorView(anchor); 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; } } mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu, anchor); mActionButtonPopup.setForceShowIcon(preserveIconSpacing); mActionButtonPopup.show(); super.onSubMenuSelected(subMenu); return true; } Loading Loading @@ -926,12 +946,9 @@ public class ActionMenuPresenter extends BaseMenuPresenter } private class ActionButtonSubmenu extends MenuPopupHelper { private SubMenuBuilder mSubMenu; public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { super(context, subMenu, null, false, public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu, View anchorView) { super(context, subMenu, anchorView, false, com.android.internal.R.attr.actionOverflowMenuStyle); mSubMenu = subMenu; MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); if (!item.isActionButton()) { Loading @@ -940,17 +957,6 @@ public class ActionMenuPresenter extends BaseMenuPresenter } 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 Loading core/java/android/widget/DropDownListView.java +55 −2 Original line number Diff line number Diff line Loading @@ -25,10 +25,8 @@ import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.IntProperty; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.TextView; import android.widget.ListView; Loading Loading @@ -128,6 +126,61 @@ public class DropDownListView extends ListView { setCacheColorHint(0); // Transparent, since the background drawable could be anything. } @Override protected boolean shouldShowSelector() { View selectedView = getSelectedView(); return selectedView != null && selectedView.isEnabled() || super.shouldShowSelector(); } protected void clearSelection() { setSelectedPositionInt(-1); setNextSelectedPositionInt(-1); } @Override public boolean onHoverEvent(MotionEvent ev) { final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE) { final int position = pointToPosition((int) ev.getX(), (int) ev.getY()); if (position != INVALID_POSITION && position != mSelectedPosition) { final View hoveredItem = getChildAt(position - getFirstVisiblePosition()); if (hoveredItem.isEnabled()) { // Force a focus so that the proper selector state gets used when we update. requestFocus(); positionSelector(position, hoveredItem); setSelectedPositionInt(position); setNextSelectedPositionInt(position); } updateSelectorState(); } } else { // Do not cancel the selected position if the selection is visible by other reasons. if (!super.shouldShowSelector()) { setSelectedPositionInt(INVALID_POSITION); } } return super.onHoverEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); final int position = pointToPosition(x, y); if (position == INVALID_POSITION) { return super.onTouchEvent(event); } if (position != mSelectedPosition) { setSelectedPositionInt(position); setNextSelectedPositionInt(position); } return super.onTouchEvent(event); } /** * Handles forwarded events. * Loading core/java/android/widget/ListPopupWindow.java +2 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ public class ListPopupWindow implements ShowableListMenu { private static final int EXPAND_LIST_TIMEOUT = 250; private Context mContext; private PopupWindow mPopup; private ListAdapter mAdapter; private DropDownListView mDropDownList; Loading Loading @@ -112,6 +111,8 @@ public class ListPopupWindow implements ShowableListMenu { private int mLayoutDirection; PopupWindow mPopup; /** * The provided prompt view should appear above list content. * Loading core/java/android/widget/MenuPopupWindow.java +54 −41 Original line number Diff line number Diff line Loading @@ -17,10 +17,17 @@ package android.widget; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.transition.Transition; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.KeyEvent; import android.view.View; import android.view.accessibility.AccessibilityManager; import android.view.ViewGroup; import android.view.ViewParent; import com.android.internal.view.menu.ListMenuItemView; import com.android.internal.view.menu.MenuAdapter; /** * A MenuPopupWindow represents the popup window for menu. Loading @@ -40,52 +47,58 @@ public class MenuPopupWindow extends ListPopupWindow { return new MenuDropDownListView(context, hijackFocus); } static class MenuDropDownListView extends DropDownListView { private boolean mHoveredOnDisabledItem = false; private AccessibilityManager mAccessibilityManager; MenuDropDownListView(Context context, boolean hijackFocus) { super(context, hijackFocus); mAccessibilityManager = (AccessibilityManager) getContext().getSystemService( Context.ACCESSIBILITY_SERVICE); public void setEnterTransition(Transition enterTransition) { mPopup.setEnterTransition(enterTransition); } @Override protected boolean shouldShowSelector() { return (isHovered() && !mHoveredOnDisabledItem) || super.shouldShowSelector(); /** * Set whether this window is touch modal or if outside touches will be sent to * other windows behind it. */ public void setTouchModal(boolean touchModal) { mPopup.setTouchModal(touchModal); } @Override public boolean onHoverEvent(MotionEvent ev) { mHoveredOnDisabledItem = false; private static class MenuDropDownListView extends DropDownListView { final int mAdvanceKey; final int mRetreatKey; // Accessibility system should already handle hover events and selections, menu does // not have to handle it by itself. if (mAccessibilityManager.isTouchExplorationEnabled()) { return super.onHoverEvent(ev); } public MenuDropDownListView(Context context, boolean hijackFocus) { super(context, hijackFocus); final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE) { final int position = pointToPosition((int) ev.getX(), (int) ev.getY()); if (position != INVALID_POSITION && position != mSelectedPosition) { final View hoveredItem = getChildAt(position - getFirstVisiblePosition()); if (hoveredItem.isEnabled()) { positionSelector(position, hoveredItem); setSelectedPositionInt(position); final Resources res = context.getResources(); final Configuration config = res.getConfiguration(); if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { mAdvanceKey = KeyEvent.KEYCODE_DPAD_LEFT; mRetreatKey = KeyEvent.KEYCODE_DPAD_RIGHT; } else { mHoveredOnDisabledItem = true; mAdvanceKey = KeyEvent.KEYCODE_DPAD_RIGHT; mRetreatKey = KeyEvent.KEYCODE_DPAD_LEFT; } updateSelectorState(); } } else { // Do not cancel the selected position if the selection is visible by other reasons. if (!super.shouldShowSelector()) { setSelectedPositionInt(INVALID_POSITION); @Override public boolean onKeyDown(int keyCode, KeyEvent event) { ListMenuItemView selectedItem = (ListMenuItemView) getSelectedView(); if (selectedItem != null && keyCode == mAdvanceKey) { if (selectedItem.isEnabled() && ((ListMenuItemView) selectedItem).getItemData().hasSubMenu()) { performItemClick( selectedItem, getSelectedItemPosition(), getSelectedItemId()); } return true; } else if (selectedItem != null && keyCode == mRetreatKey) { setSelectedPositionInt(-1); setNextSelectedPositionInt(-1); ((MenuAdapter) getAdapter()).getAdapterMenu().close(); return true; } return super.onHoverEvent(ev); return super.onKeyDown(keyCode, event); } } } No newline at end of file core/java/android/widget/PopupMenu.java +9 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { private final MenuBuilder mMenu; private final View mAnchor; private final MenuPopupHelper mPopup; private final boolean mShowCascadingMenus; private OnMenuItemClickListener mMenuItemClickListener; private OnDismissListener mDismissListener; Loading Loading @@ -107,6 +108,8 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { public PopupMenu(Context context, View anchor, int gravity, int popupStyleAttr, int popupStyleRes) { mContext = context; mShowCascadingMenus = context.getResources().getBoolean( com.android.internal.R.bool.config_enableCascadingSubmenus); mMenu = new MenuBuilder(context); mMenu.setCallback(this); mAnchor = anchor; Loading Loading @@ -273,8 +276,12 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { return true; } // Current menu will be dismissed by the normal helper, submenu will be shown in its place. if (!mShowCascadingMenus) { // Current menu will be dismissed by the normal helper, submenu will be shown in its // place. (If cascading menus are enabled, the cascading implementation will show the // submenu itself). new MenuPopupHelper(mContext, subMenu, mAnchor).show(); } return true; } Loading Loading
core/java/android/widget/ActionMenuPresenter.java +26 −20 Original line number Diff line number Diff line Loading @@ -85,6 +85,8 @@ public class ActionMenuPresenter extends BaseMenuPresenter private OpenOverflowRunnable mPostedOpenRunnable; private ActionMenuPopupCallback mPopupCallback; private final boolean mShowCascadingMenus; final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback(); int mOpenSubMenuId; Loading Loading @@ -126,6 +128,9 @@ public class ActionMenuPresenter extends BaseMenuPresenter public ActionMenuPresenter(Context context) { super(context, com.android.internal.R.layout.action_menu_layout, com.android.internal.R.layout.action_menu_item_layout); mShowCascadingMenus = context.getResources().getBoolean( com.android.internal.R.bool.config_enableCascadingSubmenus); } @Override Loading Loading @@ -500,14 +505,29 @@ public class ActionMenuPresenter extends BaseMenuPresenter } View anchor = findViewForItem(topSubMenu.getItem()); if (anchor == null) { if (mOverflowButton == null) return false; anchor = mOverflowButton; // This means the submenu was opened from an overflow menu item, indicating the // MenuPopupHelper will handle opening the submenu via its MenuPopup. Return false to // ensure that the MenuPopup acts as presenter for the submenu, and acts on its // responsibility to display the new submenu. return false; } mOpenSubMenuId = subMenu.getItem().getItemId(); mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu); mActionButtonPopup.setAnchorView(anchor); 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; } } mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu, anchor); mActionButtonPopup.setForceShowIcon(preserveIconSpacing); mActionButtonPopup.show(); super.onSubMenuSelected(subMenu); return true; } Loading Loading @@ -926,12 +946,9 @@ public class ActionMenuPresenter extends BaseMenuPresenter } private class ActionButtonSubmenu extends MenuPopupHelper { private SubMenuBuilder mSubMenu; public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) { super(context, subMenu, null, false, public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu, View anchorView) { super(context, subMenu, anchorView, false, com.android.internal.R.attr.actionOverflowMenuStyle); mSubMenu = subMenu; MenuItemImpl item = (MenuItemImpl) subMenu.getItem(); if (!item.isActionButton()) { Loading @@ -940,17 +957,6 @@ public class ActionMenuPresenter extends BaseMenuPresenter } 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 Loading
core/java/android/widget/DropDownListView.java +55 −2 Original line number Diff line number Diff line Loading @@ -25,10 +25,8 @@ import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.IntProperty; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityManager; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.TextView; import android.widget.ListView; Loading Loading @@ -128,6 +126,61 @@ public class DropDownListView extends ListView { setCacheColorHint(0); // Transparent, since the background drawable could be anything. } @Override protected boolean shouldShowSelector() { View selectedView = getSelectedView(); return selectedView != null && selectedView.isEnabled() || super.shouldShowSelector(); } protected void clearSelection() { setSelectedPositionInt(-1); setNextSelectedPositionInt(-1); } @Override public boolean onHoverEvent(MotionEvent ev) { final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE) { final int position = pointToPosition((int) ev.getX(), (int) ev.getY()); if (position != INVALID_POSITION && position != mSelectedPosition) { final View hoveredItem = getChildAt(position - getFirstVisiblePosition()); if (hoveredItem.isEnabled()) { // Force a focus so that the proper selector state gets used when we update. requestFocus(); positionSelector(position, hoveredItem); setSelectedPositionInt(position); setNextSelectedPositionInt(position); } updateSelectorState(); } } else { // Do not cancel the selected position if the selection is visible by other reasons. if (!super.shouldShowSelector()) { setSelectedPositionInt(INVALID_POSITION); } } return super.onHoverEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { final int x = (int) event.getX(); final int y = (int) event.getY(); final int position = pointToPosition(x, y); if (position == INVALID_POSITION) { return super.onTouchEvent(event); } if (position != mSelectedPosition) { setSelectedPositionInt(position); setNextSelectedPositionInt(position); } return super.onTouchEvent(event); } /** * Handles forwarded events. * Loading
core/java/android/widget/ListPopupWindow.java +2 −1 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ public class ListPopupWindow implements ShowableListMenu { private static final int EXPAND_LIST_TIMEOUT = 250; private Context mContext; private PopupWindow mPopup; private ListAdapter mAdapter; private DropDownListView mDropDownList; Loading Loading @@ -112,6 +111,8 @@ public class ListPopupWindow implements ShowableListMenu { private int mLayoutDirection; PopupWindow mPopup; /** * The provided prompt view should appear above list content. * Loading
core/java/android/widget/MenuPopupWindow.java +54 −41 Original line number Diff line number Diff line Loading @@ -17,10 +17,17 @@ package android.widget; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.transition.Transition; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.KeyEvent; import android.view.View; import android.view.accessibility.AccessibilityManager; import android.view.ViewGroup; import android.view.ViewParent; import com.android.internal.view.menu.ListMenuItemView; import com.android.internal.view.menu.MenuAdapter; /** * A MenuPopupWindow represents the popup window for menu. Loading @@ -40,52 +47,58 @@ public class MenuPopupWindow extends ListPopupWindow { return new MenuDropDownListView(context, hijackFocus); } static class MenuDropDownListView extends DropDownListView { private boolean mHoveredOnDisabledItem = false; private AccessibilityManager mAccessibilityManager; MenuDropDownListView(Context context, boolean hijackFocus) { super(context, hijackFocus); mAccessibilityManager = (AccessibilityManager) getContext().getSystemService( Context.ACCESSIBILITY_SERVICE); public void setEnterTransition(Transition enterTransition) { mPopup.setEnterTransition(enterTransition); } @Override protected boolean shouldShowSelector() { return (isHovered() && !mHoveredOnDisabledItem) || super.shouldShowSelector(); /** * Set whether this window is touch modal or if outside touches will be sent to * other windows behind it. */ public void setTouchModal(boolean touchModal) { mPopup.setTouchModal(touchModal); } @Override public boolean onHoverEvent(MotionEvent ev) { mHoveredOnDisabledItem = false; private static class MenuDropDownListView extends DropDownListView { final int mAdvanceKey; final int mRetreatKey; // Accessibility system should already handle hover events and selections, menu does // not have to handle it by itself. if (mAccessibilityManager.isTouchExplorationEnabled()) { return super.onHoverEvent(ev); } public MenuDropDownListView(Context context, boolean hijackFocus) { super(context, hijackFocus); final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_HOVER_ENTER || action == MotionEvent.ACTION_HOVER_MOVE) { final int position = pointToPosition((int) ev.getX(), (int) ev.getY()); if (position != INVALID_POSITION && position != mSelectedPosition) { final View hoveredItem = getChildAt(position - getFirstVisiblePosition()); if (hoveredItem.isEnabled()) { positionSelector(position, hoveredItem); setSelectedPositionInt(position); final Resources res = context.getResources(); final Configuration config = res.getConfiguration(); if (config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { mAdvanceKey = KeyEvent.KEYCODE_DPAD_LEFT; mRetreatKey = KeyEvent.KEYCODE_DPAD_RIGHT; } else { mHoveredOnDisabledItem = true; mAdvanceKey = KeyEvent.KEYCODE_DPAD_RIGHT; mRetreatKey = KeyEvent.KEYCODE_DPAD_LEFT; } updateSelectorState(); } } else { // Do not cancel the selected position if the selection is visible by other reasons. if (!super.shouldShowSelector()) { setSelectedPositionInt(INVALID_POSITION); @Override public boolean onKeyDown(int keyCode, KeyEvent event) { ListMenuItemView selectedItem = (ListMenuItemView) getSelectedView(); if (selectedItem != null && keyCode == mAdvanceKey) { if (selectedItem.isEnabled() && ((ListMenuItemView) selectedItem).getItemData().hasSubMenu()) { performItemClick( selectedItem, getSelectedItemPosition(), getSelectedItemId()); } return true; } else if (selectedItem != null && keyCode == mRetreatKey) { setSelectedPositionInt(-1); setNextSelectedPositionInt(-1); ((MenuAdapter) getAdapter()).getAdapterMenu().close(); return true; } return super.onHoverEvent(ev); return super.onKeyDown(keyCode, event); } } } No newline at end of file
core/java/android/widget/PopupMenu.java +9 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { private final MenuBuilder mMenu; private final View mAnchor; private final MenuPopupHelper mPopup; private final boolean mShowCascadingMenus; private OnMenuItemClickListener mMenuItemClickListener; private OnDismissListener mDismissListener; Loading Loading @@ -107,6 +108,8 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { public PopupMenu(Context context, View anchor, int gravity, int popupStyleAttr, int popupStyleRes) { mContext = context; mShowCascadingMenus = context.getResources().getBoolean( com.android.internal.R.bool.config_enableCascadingSubmenus); mMenu = new MenuBuilder(context); mMenu.setCallback(this); mAnchor = anchor; Loading Loading @@ -273,8 +276,12 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback { return true; } // Current menu will be dismissed by the normal helper, submenu will be shown in its place. if (!mShowCascadingMenus) { // Current menu will be dismissed by the normal helper, submenu will be shown in its // place. (If cascading menus are enabled, the cascading implementation will show the // submenu itself). new MenuPopupHelper(mContext, subMenu, mAnchor).show(); } return true; } Loading