MenuDialogHelper.java revision 8d37426c754e9822feaa8c6cc0b7c13e8523e217
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 Projectimport android.widget.ListAdapter;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Helper for menus that appear as Dialogs (context and submenus).
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class MenuDialogHelper implements DialogInterface.OnKeyListener, DialogInterface.OnClickListener {
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private MenuBuilder mMenu;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ListAdapter mAdapter;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private AlertDialog mDialog;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public MenuDialogHelper(MenuBuilder menu) {
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMenu = menu;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Shows menu as a dialog.
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param windowToken Optional token to assign to the window.
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void show(IBinder windowToken) {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Many references to mMenu, create local reference
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final MenuBuilder menu = mMenu;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get an adapter for the menu item views
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mAdapter = menu.getMenuAdapter(MenuBuilder.TYPE_DIALOG);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Get the builder for the dialog
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final AlertDialog.Builder builder = new AlertDialog.Builder(menu.getContext())
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                .setAdapter(mAdapter, this);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the title
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View headerView = menu.getHeaderView();
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (headerView != null) {
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Menu's client has given a custom header view, use it
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            builder.setCustomTitle(headerView);
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Otherwise use the (text) title and icon
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            builder.setIcon(menu.getHeaderIcon()).setTitle(menu.getHeaderTitle());
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the key listener
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.setOnKeyListener(this);
719c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy
729c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy        // Since this is for a menu, disable the recycling of views
739c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy        // This is done by the menu framework anyway
749c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy        builder.setRecycleOnMeasureEnabled(false);
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Show the menu
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDialog = builder.create();
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager.LayoutParams lp = mDialog.getWindow().getAttributes();
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (windowToken != null) {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            lp.token = windowToken;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDialog.show();
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
908d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn        if (keyCode == KeyEvent.KEYCODE_MENU || keyCode == KeyEvent.KEYCODE_BACK) {
918d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn            if (event.getAction() == KeyEvent.ACTION_DOWN
928d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    && event.getRepeatCount() == 0) {
938d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                Window win = mDialog.getWindow();
948d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                if (win != null) {
958d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    View decor = win.getDecorView();
968d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    if (decor != null) {
978d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                        KeyEvent.DispatcherState ds = decor.getKeyDispatcherState();
988d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                        if (ds != null) {
998d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                            ds.startTracking(event, this);
1008d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                            return true;
1018d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                        }
1028d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    }
1038d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                }
1048d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn            } else if (event.getAction() == KeyEvent.ACTION_UP
1058d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                    && event.isTracking() && !event.isCanceled()) {
1068d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                mMenu.close(true);
1078d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                dialog.dismiss();
1088d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn                return true;
1098d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn            }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Menu shortcut matching
1139c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy        return mMenu.performShortcut(keyCode, event, 0);
1149c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Dismisses the menu's dialog.
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see Dialog#dismiss()
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismiss() {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDialog != null) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDialog.dismiss();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mMenu.performItemAction((MenuItemImpl) mAdapter.getItem(which), 0);
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
133