1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.chromium.chrome.browser.appmenu;
7 import android.annotation.SuppressLint;
8 import android.view.MotionEvent;
9 import android.view.View;
10 import android.view.View.OnTouchListener;
12 import org.chromium.chrome.browser.UmaBridge;
15 * A helper class for a menu button to decide when to show the app menu and forward touch
18 * Simply construct this class and pass the class instance to a menu button as TouchListener.
19 * Then this class will handle everything regarding showing app menu for you.
21 public class AppMenuButtonHelper implements OnTouchListener {
22 private final View mMenuButton;
23 private final AppMenuHandler mMenuHandler;
24 private Runnable mOnAppMenuShownListener;
27 * @param menuButton Menu button instance that will trigger the app menu.
28 * @param menuHandler MenuHandler implementation that can show and get the app menu.
30 public AppMenuButtonHelper(View menuButton, AppMenuHandler menuHandler) {
31 mMenuButton = menuButton;
32 mMenuHandler = menuHandler;
36 * @param onAppMenuShownListener This is called when the app menu is shown by this class.
38 public void setOnAppMenuShownListener(Runnable onAppMenuShownListener) {
39 mOnAppMenuShownListener = onAppMenuShownListener;
43 * Shows the app menu if it is not already shown.
44 * @param startDragging Whether dragging is started.
45 * @return Whether or not if the app menu is successfully shown.
47 private boolean showAppMenu(boolean startDragging) {
48 if (!mMenuHandler.isAppMenuShowing() &&
49 mMenuHandler.showAppMenu(mMenuButton, false, startDragging)) {
50 // Initial start dragging can be canceled in case if it was just single tap.
51 // So we only record non-dragging here, and will deal with those dragging cases in
52 // AppMenuDragHelper class.
53 if (!startDragging) UmaBridge.usingMenu(false, false);
55 if (mOnAppMenuShownListener != null) {
56 mOnAppMenuShownListener.run();
64 * @return Whether app menu is active. That is, AppMenu is showing or menu button is consuming
65 * touch events to prepare AppMenu showing.
67 public boolean isAppMenuActive() {
68 return mMenuButton.isPressed() || mMenuHandler.isAppMenuShowing();
72 * Handle the key press event on a menu button.
73 * @return Whether the app menu was shown as a result of this action.
75 public boolean onEnterKeyPress() {
76 return showAppMenu(false);
79 @SuppressLint("ClickableViewAccessibility")
81 public boolean onTouch(View view, MotionEvent event) {
82 boolean isTouchEventConsumed = false;
84 switch (event.getActionMasked()) {
85 case MotionEvent.ACTION_DOWN:
86 isTouchEventConsumed |= true;
87 mMenuButton.setPressed(true);
90 case MotionEvent.ACTION_UP:
91 case MotionEvent.ACTION_CANCEL:
92 isTouchEventConsumed |= true;
93 mMenuButton.setPressed(false);
98 // If user starts to drag on this menu button, ACTION_DOWN and all the subsequent touch
99 // events are received here. We need to forward this event to the app menu to handle
100 // dragging correctly.
101 AppMenuDragHelper dragHelper = mMenuHandler.getAppMenuDragHelper();
102 if (dragHelper != null) {
103 isTouchEventConsumed |= dragHelper.handleDragging(event);
105 return isTouchEventConsumed;