[go: nahoru, domu]

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/**
29021627eb5875372dea57ba91fa782fffbfbbc559Alan Viverette * Presents a menu as a modal dialog.
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
31021627eb5875372dea57ba91fa782fffbfbbc559Alan Viverettepublic class MenuDialogHelper implements MenuHelper, DialogInterface.OnKeyListener,
32021627eb5875372dea57ba91fa782fffbfbbc559Alan Viverette        DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
33696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        MenuPresenter.Callback {
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private MenuBuilder mMenu;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private AlertDialog mDialog;
36696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    ListMenuPresenter mPresenter;
37d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell    private MenuPresenter.Callback mPresenterCallback;
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 the builder for the dialog
53696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        final AlertDialog.Builder builder = new AlertDialog.Builder(menu.getContext());
54696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
55696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mPresenter = new ListMenuPresenter(builder.getContext(),
56696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell                com.android.internal.R.layout.list_menu_item_layout);
57696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
58696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mPresenter.setCallback(this);
59696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mMenu.addMenuPresenter(mPresenter);
60696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        builder.setAdapter(mPresenter.getAdapter(), this);
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the title
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final View headerView = menu.getHeaderView();
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (headerView != null) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Menu's client has given a custom header view, use it
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            builder.setCustomTitle(headerView);
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Otherwise use the (text) title and icon
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            builder.setIcon(menu.getHeaderIcon()).setTitle(menu.getHeaderTitle());
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Set the key listener
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        builder.setOnKeyListener(this);
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Show the menu
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDialog = builder.create();
77696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mDialog.setOnDismissListener(this);
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                }
1046024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell            } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled()) {
1056024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                Window win = mDialog.getWindow();
1066024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                if (win != null) {
1076024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                    View decor = win.getDecorView();
1086024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                    if (decor != null) {
1096024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                        KeyEvent.DispatcherState ds = decor.getKeyDispatcherState();
1106024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                        if (ds != null && ds.isTracking(event)) {
11100aa5103e2f71ad3f29f53168e37ef7da8ca03f2Alan Viverette                            mMenu.close(true /* closeAllMenus */);
1126024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                            dialog.dismiss();
1136024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                            return true;
1146024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                        }
1156024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                    }
1166024ca5c90203b6c33acc6adfbf7e4e613549a0aAdam Powell                }
1178d37426c754e9822feaa8c6cc0b7c13e8523e217Dianne Hackborn            }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Menu shortcut matching
1219c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy        return mMenu.performShortcut(keyCode, event, 0);
1229c802c1e95befbd8de30ea4ebc48ae05cb948b2bRomain Guy
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
125021627eb5875372dea57ba91fa782fffbfbbc559Alan Viverette    @Override
126d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell    public void setPresenterCallback(MenuPresenter.Callback cb) {
127d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell        mPresenterCallback = cb;
128d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell    }
129d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Dismisses the menu's dialog.
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see Dialog#dismiss()
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
135021627eb5875372dea57ba91fa782fffbfbbc559Alan Viverette    @Override
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void dismiss() {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDialog != null) {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDialog.dismiss();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
141696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
142696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
143696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void onDismiss(DialogInterface dialog) {
144696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mPresenter.onCloseMenu(mMenu, true);
145696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
146696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
147696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
148696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
149696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        if (allMenusAreClosing || menu == mMenu) {
150696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell            dismiss();
151696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        }
152d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell        if (mPresenterCallback != null) {
153d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell            mPresenterCallback.onCloseMenu(menu, allMenusAreClosing);
154d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell        }
155696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
156696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
157696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    @Override
158696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    public boolean onOpenSubMenu(MenuBuilder subMenu) {
159d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell        if (mPresenterCallback != null) {
160d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell            return mPresenterCallback.onOpenSubMenu(subMenu);
161d1f4207ba577e2ac3f39a719f8ee4bb9f4940dc1Adam Powell        }
162696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        return false;
163696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell    }
164696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onClick(DialogInterface dialog, int which) {
166696cba573e651b0e4f18a4718627c8ccecb3bda0Adam Powell        mMenu.performItemAction((MenuItemImpl) mPresenter.getAdapter().getItem(which), 0);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
169