MenuDialogHelper.java revision 696cba573e651b0e4f18a4718627c8ccecb3bda0
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.view.menu; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.AlertDialog; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Dialog; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.DialogInterface; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 258d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackbornimport android.view.Window; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper for menus that appear as Dialogs (context and submenus). 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 33696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powellpublic class MenuDialogHelper implements DialogInterface.OnKeyListener, 34696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell DialogInterface.OnClickListener, 35696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell DialogInterface.OnDismissListener, 36696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell MenuPresenter.Callback { 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private MenuBuilder mMenu; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private AlertDialog mDialog; 39696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell ListMenuPresenter mPresenter; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public MenuDialogHelper(MenuBuilder menu) { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMenu = menu; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Shows menu as a dialog. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param windowToken Optional token to assign to the window. 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void show(IBinder windowToken) { 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Many references to mMenu, create local reference 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final MenuBuilder menu = mMenu; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the builder for the dialog 55696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell final AlertDialog.Builder builder = new AlertDialog.Builder(menu.getContext()); 56696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 57696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter = new ListMenuPresenter(builder.getContext(), 58696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell com.android.internal.R.layout.list_menu_item_layout); 59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 60696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter.setCallback(this); 61696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMenu.addMenuPresenter(mPresenter); 62696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell builder.setAdapter(mPresenter.getAdapter(), this); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the title 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View headerView = menu.getHeaderView(); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (headerView != null) { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Menu's client has given a custom header view, use it 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.setCustomTitle(headerView); 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Otherwise use the (text) title and icon 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.setIcon(menu.getHeaderIcon()).setTitle(menu.getHeaderTitle()); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the key listener 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project builder.setOnKeyListener(this); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Show the menu 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDialog = builder.create(); 79696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mDialog.setOnDismissListener(this); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams lp = mDialog.getWindow().getAttributes(); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (windowToken != null) { 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.token = windowToken; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDialog.show(); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { 928d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn if (keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_BACK) { 938d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn if (event.getAction() == KeyEvent.ACTION_DOWN 948d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn && event.getRepeatCount() == 0) { 958d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn Window win = mDialog.getWindow(); 968d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn if (win != null) { 978d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn View decor = win.getDecorView(); 988d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn if (decor != null) { 998d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn KeyEvent.DispatcherState ds = decor.getKeyDispatcherState(); 1008d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn if (ds != null) { 1018d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn ds.startTracking(event, this); 1028d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn return true; 1038d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 1048d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 1058d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 1066024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled()) { 1076024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell Window win = mDialog.getWindow(); 1086024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell if (win != null) { 1096024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell View decor = win.getDecorView(); 1106024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell if (decor != null) { 1116024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell KeyEvent.DispatcherState ds = decor.getKeyDispatcherState(); 1126024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell if (ds != null && ds.isTracking(event)) { 1136024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell mMenu.close(true); 1146024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell dialog.dismiss(); 1156024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell return true; 1166024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell } 1176024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell } 1186024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell } 1198d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Menu shortcut matching 1239c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy return mMenu.performShortcut(keyCode, event, 0); 1249c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Dismisses the menu's dialog. 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Dialog#dismiss() 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void dismiss() { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDialog != null) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDialog.dismiss(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 137696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 138696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 139696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void onDismiss(DialogInterface dialog) { 140696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mPresenter.onCloseMenu(mMenu, true); 141696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 142696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 143696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 144696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { 145696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell if (allMenusAreClosing || menu == mMenu) { 146696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell dismiss(); 147696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 148696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 149696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 150696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell @Override 151696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell public boolean onOpenSubMenu(MenuBuilder subMenu) { 152696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell return false; 153696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell } 154696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onClick(DialogInterface dialog, int which) { 156696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell mMenu.performItemAction((MenuItemImpl) mPresenter.getAdapter().getItem(which), 0); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 159