blob: ea7998339f3b9c5922810d39cc923e72415b26e4 [file] [log] [blame]
Adam Powell42675342010-07-09 18:02:59 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.view.menu;
18
Oren Blasberg99162822015-09-10 14:37:26 -070019import com.android.internal.view.menu.MenuPresenter.Callback;
20
Adam Powell42675342010-07-09 18:02:59 -070021import android.content.Context;
Adam Powell54c94de2013-09-26 15:36:34 -070022import android.view.Gravity;
Adam Powell42675342010-07-09 18:02:59 -070023import android.view.View;
Adam Powell6c6f5752010-08-20 18:34:46 -070024import android.widget.PopupWindow;
Adam Powell42675342010-07-09 18:02:59 -070025
26/**
Adam Powell696cba52011-03-29 10:38:16 -070027 * Presents a menu as a small, simple popup anchored to another view.
Oren Blasbergb23976e2015-09-01 14:55:42 -070028 *
Adam Powell42675342010-07-09 18:02:59 -070029 * @hide
30 */
Oren Blasberg99162822015-09-10 14:37:26 -070031public class MenuPopupHelper implements PopupWindow.OnDismissListener {
Alan Viverette0bce6ab2013-06-26 17:46:16 -070032 private final Context mContext;
Alan Viverette0bce6ab2013-06-26 17:46:16 -070033 private final MenuBuilder mMenu;
Alan Viverette0bce6ab2013-06-26 17:46:16 -070034 private final boolean mOverflowOnly;
Alan Viverette560f1702014-05-05 14:40:07 -070035 private final int mPopupStyleAttr;
Alan Viverette29632522014-10-15 17:19:30 -070036 private final int mPopupStyleRes;
Alan Viverette0bce6ab2013-06-26 17:46:16 -070037
Adam Powell4afd62b2011-02-18 15:02:18 -080038 private View mAnchorView;
Oren Blasbergb23976e2015-09-01 14:55:42 -070039 private MenuPopup mPopup;
Alan Viverette0bce6ab2013-06-26 17:46:16 -070040
Adam Powell54c94de2013-09-26 15:36:34 -070041 private int mDropDownGravity = Gravity.NO_GRAVITY;
Oren Blasberg99162822015-09-10 14:37:26 -070042 private Callback mPresenterCallback;
Adam Powell54c94de2013-09-26 15:36:34 -070043
Adam Powell8028dd32010-07-15 10:16:33 -070044 public MenuPopupHelper(Context context, MenuBuilder menu) {
Alan Viverette29632522014-10-15 17:19:30 -070045 this(context, menu, null, false, com.android.internal.R.attr.popupMenuStyle, 0);
Adam Powell8028dd32010-07-15 10:16:33 -070046 }
47
48 public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView) {
Alan Viverette29632522014-10-15 17:19:30 -070049 this(context, menu, anchorView, false, com.android.internal.R.attr.popupMenuStyle, 0);
Adam Powell8028dd32010-07-15 10:16:33 -070050 }
51
Alan Viverette560f1702014-05-05 14:40:07 -070052 public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView,
53 boolean overflowOnly, int popupStyleAttr) {
Alan Viverette29632522014-10-15 17:19:30 -070054 this(context, menu, anchorView, overflowOnly, popupStyleAttr, 0);
55 }
56
57 public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView,
58 boolean overflowOnly, int popupStyleAttr, int popupStyleRes) {
Adam Powell42675342010-07-09 18:02:59 -070059 mContext = context;
Adam Powell8028dd32010-07-15 10:16:33 -070060 mMenu = menu;
61 mOverflowOnly = overflowOnly;
Alan Viverette560f1702014-05-05 14:40:07 -070062 mPopupStyleAttr = popupStyleAttr;
Alan Viverette29632522014-10-15 17:19:30 -070063 mPopupStyleRes = popupStyleRes;
Adam Powell4afd62b2011-02-18 15:02:18 -080064 mAnchorView = anchorView;
Oren Blasbergb23976e2015-09-01 14:55:42 -070065 mPopup = createMenuPopup();
66 }
Adam Powell696cba52011-03-29 10:38:16 -070067
Oren Blasbergb23976e2015-09-01 14:55:42 -070068 private MenuPopup createMenuPopup() {
69 if (mContext.getResources().getBoolean(
70 com.android.internal.R.bool.config_enableCascadingSubmenus)) {
Oren Blasberg8e12f8d2015-09-02 14:25:56 -070071 return new CascadingMenuPopup(mContext, mAnchorView, mPopupStyleAttr, mPopupStyleRes,
72 mOverflowOnly);
Oren Blasbergb23976e2015-09-01 14:55:42 -070073 }
74 return new StandardMenuPopup(
75 mContext, mMenu, mAnchorView, mPopupStyleAttr, mPopupStyleRes, mOverflowOnly);
Adam Powell42675342010-07-09 18:02:59 -070076 }
77
Adam Powellf0ad6e62011-01-10 17:14:06 -080078 public void setAnchorView(View anchor) {
Adam Powell4afd62b2011-02-18 15:02:18 -080079 mAnchorView = anchor;
Oren Blasbergb23976e2015-09-01 14:55:42 -070080 mPopup.setAnchorView(anchor);
Adam Powellf0ad6e62011-01-10 17:14:06 -080081 }
82
Adam Powell91511032011-07-13 10:24:06 -070083 public void setForceShowIcon(boolean forceShow) {
Oren Blasbergb23976e2015-09-01 14:55:42 -070084 mPopup.setForceShowIcon(forceShow);
Adam Powell91511032011-07-13 10:24:06 -070085 }
86
Adam Powell54c94de2013-09-26 15:36:34 -070087 public void setGravity(int gravity) {
88 mDropDownGravity = gravity;
Oren Blasbergb23976e2015-09-01 14:55:42 -070089 mPopup.setGravity(gravity);
Adam Powell54c94de2013-09-26 15:36:34 -070090 }
91
Alan Viverette75d83792015-01-07 15:51:54 -080092 public int getGravity() {
93 return mDropDownGravity;
94 }
95
Adam Powell42675342010-07-09 18:02:59 -070096 public void show() {
Adam Powell5e3f2842011-01-07 17:16:56 -080097 if (!tryShow()) {
98 throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
99 }
100 }
101
Oren Blasbergb23976e2015-09-01 14:55:42 -0700102 public ShowableListMenu getPopup() {
Alan Viveretteca6a36112013-08-16 14:41:06 -0700103 return mPopup;
104 }
105
Alan Viverette8fd949e2015-03-11 12:21:30 -0700106 /**
Oren Blasbergb23976e2015-09-01 14:55:42 -0700107 * Attempts to show the popup anchored to the view specified by {@link #setAnchorView(View)}.
Alan Viverette8fd949e2015-03-11 12:21:30 -0700108 *
Oren Blasbergb23976e2015-09-01 14:55:42 -0700109 * @return {@code true} if the popup was shown or was already showing prior to calling this
110 * method, {@code false} otherwise
Alan Viverette8fd949e2015-03-11 12:21:30 -0700111 */
Adam Powell5e3f2842011-01-07 17:16:56 -0800112 public boolean tryShow() {
Alan Viverette8fd949e2015-03-11 12:21:30 -0700113 if (isShowing()) {
114 return true;
115 }
116
Oren Blasberg99162822015-09-10 14:37:26 -0700117 if (mAnchorView == null) {
Adam Powell5e3f2842011-01-07 17:16:56 -0800118 return false;
Adam Powell8028dd32010-07-15 10:16:33 -0700119 }
Adam Powell42675342010-07-09 18:02:59 -0700120
Oren Blasberg99162822015-09-10 14:37:26 -0700121 mPopup = createMenuPopup();
122 mPopup.setAnchorView(mAnchorView);
123 mPopup.setGravity(mDropDownGravity);
124 mPopup.setCallback(mPresenterCallback);
125
Oren Blasbergb23976e2015-09-01 14:55:42 -0700126 // In order for subclasses of MenuPopupHelper to satisfy the OnDismissedListener interface,
127 // we must set the listener to this outer Helper rather than to the inner MenuPopup.
128 // Not to worry -- the inner MenuPopup will call our own #onDismiss method after it's done
129 // its own handling.
130 mPopup.setOnDismissListener(this);
Alan Viverette0bce6ab2013-06-26 17:46:16 -0700131
Oren Blasbergb23976e2015-09-01 14:55:42 -0700132 mPopup.addMenu(mMenu);
Adam Powell42675342010-07-09 18:02:59 -0700133 mPopup.show();
Adam Powell5e3f2842011-01-07 17:16:56 -0800134 return true;
Adam Powell42675342010-07-09 18:02:59 -0700135 }
136
137 public void dismiss() {
Adam Powell3d3da272010-08-11 18:06:17 -0700138 if (isShowing()) {
139 mPopup.dismiss();
140 }
Adam Powell8515ee82010-11-30 14:09:55 -0800141 }
142
Alan Viverette8fd949e2015-03-11 12:21:30 -0700143 @Override
Adam Powell8515ee82010-11-30 14:09:55 -0800144 public void onDismiss() {
145 mPopup = null;
Adam Powell42675342010-07-09 18:02:59 -0700146 }
147
Adam Powell8028dd32010-07-15 10:16:33 -0700148 public boolean isShowing() {
149 return mPopup != null && mPopup.isShowing();
150 }
151
Adam Powell696cba52011-03-29 10:38:16 -0700152
Oren Blasberg8e12f8d2015-09-02 14:25:56 -0700153 public void setCallback(MenuPresenter.Callback cb) {
Oren Blasberg99162822015-09-10 14:37:26 -0700154 mPresenterCallback = cb;
Oren Blasbergb23976e2015-09-01 14:55:42 -0700155 mPopup.setCallback(cb);
Adam Powell696cba52011-03-29 10:38:16 -0700156 }
Adam Powell42675342010-07-09 18:02:59 -0700157}