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.app.Activity;
8 import android.view.ContextThemeWrapper;
9 import android.view.Menu;
10 import android.view.View;
11 import android.widget.PopupMenu;
13 import org.chromium.chrome.browser.UmaBridge;
15 import java.util.ArrayList;
18 * Object responsible for handling the creation, showing, hiding of the AppMenu and notifying the
19 * AppMenuObservers about these actions.
21 public class AppMenuHandler {
22 private AppMenu mAppMenu;
24 private final ArrayList<AppMenuObserver> mObservers;
25 private final int mMenuResourceId;
27 private final AppMenuPropertiesDelegate mDelegate;
28 private final Activity mActivity;
31 * Constructs an AppMenuHandler object.
32 * @param activity Activity that is using the AppMenu.
33 * @param delegate Delegate used to check the desired AppMenu properties on show.
34 * @param menuResourceId Resource Id that should be used as the source for the menu items.
35 * It is assumed to have back_menu_id, forward_menu_id, bookmark_this_page_id.
37 public AppMenuHandler(Activity activity, AppMenuPropertiesDelegate delegate,
41 mObservers = new ArrayList<AppMenuObserver>();
42 mMenuResourceId = menuResourceId;
47 * @param anchorView Anchor view (usually a menu button) to be used for the popup.
48 * @param isByHardwareButton True if hardware button triggered it. (oppose to software
50 * @param startDragging Whether dragging is started. For example, if the app menu is
51 * showed by tapping on a button, this should be false. If it is
52 * showed by start dragging down on the menu button, this should
53 * be true. Note that if isByHardwareButton is true, this is
55 * @return True, if the menu is shown, false, if menu is not shown, example reasons:
56 * the menu is not yet available to be shown, or the menu is already showing.
58 public boolean showAppMenu(View anchorView, boolean isByHardwareButton, boolean startDragging) {
59 if (!mDelegate.shouldShowAppMenu()) return false;
62 // Use a PopupMenu to create the Menu object. Note this is not the same as the
63 // AppMenu (mAppMenu) created below.
64 PopupMenu tempMenu = new PopupMenu(mActivity, anchorView);
65 tempMenu.inflate(mMenuResourceId);
66 mMenu = tempMenu.getMenu();
68 mDelegate.prepareMenu(mMenu);
70 if (mAppMenu == null) {
71 mAppMenu = new AppMenu(mActivity, mMenu, mDelegate.getItemRowHeight(), this);
74 ContextThemeWrapper wrapper = new ContextThemeWrapper(mActivity,
75 mDelegate.getMenuThemeResourceId());
76 boolean showIcons = mDelegate.shouldShowIconRow();
77 mAppMenu.show(wrapper, anchorView, showIcons, isByHardwareButton, startDragging);
83 * @return Whether the App Menu is currently showing.
85 public boolean isAppMenuShowing() {
86 return mAppMenu != null && mAppMenu.isShowing();
90 * @return The App Menu that the menu handler is interacting with.
92 AppMenu getAppMenu() {
97 * Requests to hide the App Menu.
99 public void hideAppMenu() {
100 if (mAppMenu != null && mAppMenu.isShowing()) mAppMenu.dismiss();
104 * @return The number of items in the AppMenu.
106 public int getItemCount() {
107 if (mAppMenu == null) return -1;
108 return mAppMenu.getCount();
112 * Adds the observer to App Menu.
113 * @param observer Observer that should be notified about App Menu changes.
115 public void addObserver(AppMenuObserver observer) {
116 mObservers.add(observer);
120 * Removes the observer from the App Menu.
121 * @param observer Observer that should no longer be notified about App Menu changes.
123 public void removeObserver(AppMenuObserver observer) {
124 mObservers.remove(observer);
128 * Called by AppMenu to report that the App Menu visibility has changed.
129 * @param newState Whether the App Menu is showing.
130 * @param focusedPosition The current focused position.
132 void onMenuVisibilityChanged(boolean newState, int focusedPosition) {
133 for (int i = 0; i < mObservers.size(); ++i) {
134 mObservers.get(i).onMenuVisibilityChanged(newState, focusedPosition);
139 * Called by AppMenu to report that the keyboard focus has changed.
140 * @param focusedPosition The new focused position.
142 void onKeyboardFocusChanged(int focusedPosition) {
143 for (int i = 0; i < mObservers.size(); ++i) {
144 mObservers.get(i).onKeyboardFocusChanged(focusedPosition);
149 * Called by AppMenu to report that the keyboard has activated an item.
150 * @param focusedPosition The activated item.
152 void onKeyboardActivatedItem(int focusedPosition) {
153 for (int i = 0; i < mObservers.size(); ++i) {
154 mObservers.get(i).onKeyboardActivatedItem(focusedPosition);
159 * TODO(kkimlabs) remove this call.
161 public void hardwareMenuButtonUp() {
162 if (mAppMenu != null) mAppMenu.hardwareMenuButtonUp();