blob: 5c8e057a9705eea35127586bd787898ed44fe8c8 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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
19import android.app.AlertDialog;
20import android.app.Dialog;
21import android.content.DialogInterface;
22import android.os.IBinder;
23import android.view.KeyEvent;
24import android.view.View;
Dianne Hackborn8d374262009-09-14 21:21:52 -070025import android.view.Window;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
28/**
29 * Helper for menus that appear as Dialogs (context and submenus).
30 *
31 * @hide
32 */
Adam Powell696cba52011-03-29 10:38:16 -070033public class MenuDialogHelper implements DialogInterface.OnKeyListener,
34 DialogInterface.OnClickListener,
35 DialogInterface.OnDismissListener,
36 MenuPresenter.Callback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 private MenuBuilder mMenu;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038 private AlertDialog mDialog;
Adam Powell696cba52011-03-29 10:38:16 -070039 ListMenuPresenter mPresenter;
Adam Powelld1f42072011-05-03 17:20:14 -070040 private MenuPresenter.Callback mPresenterCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
42 public MenuDialogHelper(MenuBuilder menu) {
43 mMenu = menu;
44 }
45
46 /**
47 * Shows menu as a dialog.
48 *
49 * @param windowToken Optional token to assign to the window.
50 */
51 public void show(IBinder windowToken) {
52 // Many references to mMenu, create local reference
53 final MenuBuilder menu = mMenu;
54
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 // Get the builder for the dialog
Adam Powell696cba52011-03-29 10:38:16 -070056 final AlertDialog.Builder builder = new AlertDialog.Builder(menu.getContext());
57
58 mPresenter = new ListMenuPresenter(builder.getContext(),
59 com.android.internal.R.layout.list_menu_item_layout);
60
61 mPresenter.setCallback(this);
62 mMenu.addMenuPresenter(mPresenter);
63 builder.setAdapter(mPresenter.getAdapter(), this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064
65 // Set the title
66 final View headerView = menu.getHeaderView();
67 if (headerView != null) {
68 // Menu's client has given a custom header view, use it
69 builder.setCustomTitle(headerView);
70 } else {
71 // Otherwise use the (text) title and icon
72 builder.setIcon(menu.getHeaderIcon()).setTitle(menu.getHeaderTitle());
73 }
74
75 // Set the key listener
76 builder.setOnKeyListener(this);
77
78 // Show the menu
79 mDialog = builder.create();
Adam Powell696cba52011-03-29 10:38:16 -070080 mDialog.setOnDismissListener(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
82 WindowManager.LayoutParams lp = mDialog.getWindow().getAttributes();
83 lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
84 if (windowToken != null) {
85 lp.token = windowToken;
86 }
87 lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
88
89 mDialog.show();
90 }
91
92 public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
Dianne Hackborn8d374262009-09-14 21:21:52 -070093 if (keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_BACK) {
94 if (event.getAction() == KeyEvent.ACTION_DOWN
95 && event.getRepeatCount() == 0) {
96 Window win = mDialog.getWindow();
97 if (win != null) {
98 View decor = win.getDecorView();
99 if (decor != null) {
100 KeyEvent.DispatcherState ds = decor.getKeyDispatcherState();
101 if (ds != null) {
102 ds.startTracking(event, this);
103 return true;
104 }
105 }
106 }
Adam Powell6024ca52010-04-02 16:05:20 -0700107 } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled()) {
108 Window win = mDialog.getWindow();
109 if (win != null) {
110 View decor = win.getDecorView();
111 if (decor != null) {
112 KeyEvent.DispatcherState ds = decor.getKeyDispatcherState();
113 if (ds != null && ds.isTracking(event)) {
114 mMenu.close(true);
115 dialog.dismiss();
116 return true;
117 }
118 }
119 }
Dianne Hackborn8d374262009-09-14 21:21:52 -0700120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121 }
122
123 // Menu shortcut matching
Romain Guy9c802c12009-03-25 15:07:31 -0700124 return mMenu.performShortcut(keyCode, event, 0);
125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 }
127
Adam Powelld1f42072011-05-03 17:20:14 -0700128 public void setPresenterCallback(MenuPresenter.Callback cb) {
129 mPresenterCallback = cb;
130 }
131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 /**
133 * Dismisses the menu's dialog.
134 *
135 * @see Dialog#dismiss()
136 */
137 public void dismiss() {
138 if (mDialog != null) {
139 mDialog.dismiss();
140 }
141 }
Adam Powell696cba52011-03-29 10:38:16 -0700142
143 @Override
144 public void onDismiss(DialogInterface dialog) {
145 mPresenter.onCloseMenu(mMenu, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 }
Adam Powell696cba52011-03-29 10:38:16 -0700147
148 @Override
149 public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
150 if (allMenusAreClosing || menu == mMenu) {
151 dismiss();
152 }
Adam Powelld1f42072011-05-03 17:20:14 -0700153 if (mPresenterCallback != null) {
154 mPresenterCallback.onCloseMenu(menu, allMenusAreClosing);
155 }
Adam Powell696cba52011-03-29 10:38:16 -0700156 }
157
158 @Override
159 public boolean onOpenSubMenu(MenuBuilder subMenu) {
Adam Powelld1f42072011-05-03 17:20:14 -0700160 if (mPresenterCallback != null) {
161 return mPresenterCallback.onOpenSubMenu(subMenu);
162 }
Adam Powell696cba52011-03-29 10:38:16 -0700163 return false;
164 }
165
166 public void onClick(DialogInterface dialog, int which) {
167 mMenu.performItemAction((MenuItemImpl) mPresenter.getAdapter().getItem(which), 0);
168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169}