149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes/*
249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Copyright (C) 2014 The Android Open Source Project
349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *
449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Licensed under the Apache License, Version 2.0 (the "License");
549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * you may not use this file except in compliance with the License.
649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * You may obtain a copy of the License at
749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *
849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *      http://www.apache.org/licenses/LICENSE-2.0
949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes *
1049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * Unless required by applicable law or agreed to in writing, software
1149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * distributed under the License is distributed on an "AS IS" BASIS,
1249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * See the License for the specific language governing permissions and
1449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes * limitations under the License.
1549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes */
1649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
1766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banespackage android.support.v7.app;
1849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
1949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.content.Context;
2049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.content.res.Configuration;
2157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banesimport android.content.res.Resources;
2249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.graphics.drawable.Drawable;
2349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.annotation.Nullable;
2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v4.view.ViewCompat;
25ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banesimport android.support.v7.appcompat.R;
2666698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.WindowCallbackWrapper;
2766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.ListMenuPresenter;
2866698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuBuilder;
2966698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.view.menu.MenuPresenter;
3066698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.DecorToolbar;
3149c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.support.v7.widget.Toolbar;
3266698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesimport android.support.v7.widget.ToolbarWidgetWrapper;
3357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banesimport android.util.TypedValue;
3457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banesimport android.view.ContextThemeWrapper;
359d9c6a22548670bf017e69fd5d0f47134a18b53fChris Banesimport android.view.KeyCharacterMap;
3649c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.KeyEvent;
3749c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.LayoutInflater;
3849c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.Menu;
3949c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.MenuItem;
4049c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.View;
41a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mountimport android.view.ViewGroup;
4249c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.Window;
4349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.widget.SpinnerAdapter;
4449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
4549c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport java.util.ArrayList;
4649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
4766698bb15ba0f873aa1c2290cc50d6bb839a474aChris Banesclass ToolbarActionBar extends ActionBar {
482c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas    DecorToolbar mDecorToolbar;
492c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas    boolean mToolbarMenuPrepared;
502c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas    Window.Callback mWindowCallback;
51c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    private boolean mMenuCallbackSet;
5249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
5349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private boolean mLastMenuVisibility;
548d4765883ff24f0f79bf64fea23d4687d50cec85Chris Banes    private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners = new ArrayList<>();
5549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
5657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes    private ListMenuPresenter mListMenuPresenter;
5757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
5849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private final Runnable mMenuInvalidator = new Runnable() {
5949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        @Override
6049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public void run() {
6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            populateOptionsMenu();
6249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
6349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    };
6449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
6549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private final Toolbar.OnMenuItemClickListener mMenuClicker =
6649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            new Toolbar.OnMenuItemClickListener() {
6749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                @Override
6849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                public boolean onMenuItemClick(MenuItem item) {
6949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    return mWindowCallback.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
7049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                }
7149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            };
7249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
738d4765883ff24f0f79bf64fea23d4687d50cec85Chris Banes    public ToolbarActionBar(Toolbar toolbar, CharSequence title, Window.Callback callback) {
74a2c72b87007d10202c25e78e904938f770c6337dChris Banes        mDecorToolbar = new ToolbarWidgetWrapper(toolbar, false);
758d4765883ff24f0f79bf64fea23d4687d50cec85Chris Banes        mWindowCallback = new ToolbarCallbackWrapper(callback);
7649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setWindowCallback(mWindowCallback);
7749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        toolbar.setOnMenuItemClickListener(mMenuClicker);
7849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setWindowTitle(title);
7949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
8049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
81f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes    public Window.Callback getWrappedWindowCallback() {
820b216f2263135782c361e122892a12156d5d2ce1Chris Banes        return mWindowCallback;
830b216f2263135782c361e122892a12156d5d2ce1Chris Banes    }
840b216f2263135782c361e122892a12156d5d2ce1Chris Banes
8549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
8649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setCustomView(View view) {
8749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        setCustomView(view, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
8849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
8949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
9049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
9149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setCustomView(View view, LayoutParams layoutParams) {
9200374d6956602a63c2d57b1962131b175e20d811Adam Powell        if (view != null) {
9300374d6956602a63c2d57b1962131b175e20d811Adam Powell            view.setLayoutParams(layoutParams);
9400374d6956602a63c2d57b1962131b175e20d811Adam Powell        }
9549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setCustomView(view);
9649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
9749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
9849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
9949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setCustomView(int resId) {
1006aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        final LayoutInflater inflater = LayoutInflater.from(mDecorToolbar.getContext());
1016aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        setCustomView(inflater.inflate(resId, mDecorToolbar.getViewGroup(), false));
10249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
10349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
10449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
10549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setIcon(int resId) {
10649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setIcon(resId);
10749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
10849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
10949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
11049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setIcon(Drawable icon) {
11149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setIcon(icon);
11249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
11349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
11449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
11549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setLogo(int resId) {
11649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setLogo(resId);
11749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
11849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
11949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
12049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setLogo(Drawable logo) {
12149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setLogo(logo);
12249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
12349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
12449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
12549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setStackedBackgroundDrawable(Drawable d) {
12649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // This space for rent (do nothing)
12749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
12849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
12949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
13049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setSplitBackgroundDrawable(Drawable d) {
13149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // This space for rent (do nothing)
13249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
13349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
13449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
13549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setHomeButtonEnabled(boolean enabled) {
13649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // If the nav button on a Toolbar is present, it's enabled. No-op.
13749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
13849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
13949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
14049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setElevation(float elevation) {
1416aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        ViewCompat.setElevation(mDecorToolbar.getViewGroup(), elevation);
14249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
14349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
14449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
14549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public float getElevation() {
1466aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return ViewCompat.getElevation(mDecorToolbar.getViewGroup());
14749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
14849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
14949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
15049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public Context getThemedContext() {
1516aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return mDecorToolbar.getContext();
15249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
15349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
15449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
15549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean isTitleTruncated() {
15649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return super.isTitleTruncated();
15749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
15849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
15949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
16049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setHomeAsUpIndicator(Drawable indicator) {
1616aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        mDecorToolbar.setNavigationIcon(indicator);
16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
16349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
16449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
16549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setHomeAsUpIndicator(int resId) {
1666aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        mDecorToolbar.setNavigationIcon(resId);
16749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
16849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
16949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
17049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setHomeActionContentDescription(CharSequence description) {
171b3813e08451b31c599f47ebaf14c9467043cedbcYigit Boyar        mDecorToolbar.setNavigationContentDescription(description);
17249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
17349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
17449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
17549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDefaultDisplayHomeAsUpEnabled(boolean enabled) {
17649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // Do nothing
17749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
17849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
17949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
18049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setHomeActionContentDescription(int resId) {
181b3813e08451b31c599f47ebaf14c9467043cedbcYigit Boyar        mDecorToolbar.setNavigationContentDescription(resId);
18249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
18349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
18449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
18549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setShowHideAnimationEnabled(boolean enabled) {
18649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // This space for rent; no-op.
18749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
18849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
18949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
19049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void onConfigurationChanged(Configuration config) {
19149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        super.onConfigurationChanged(config);
19249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
19349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
19449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
19549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
19649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setDropdownParams(adapter, new NavItemSelectedListener(callback));
19749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
19849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
19949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
20049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setSelectedNavigationItem(int position) {
20149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        switch (mDecorToolbar.getNavigationMode()) {
20249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            case NAVIGATION_MODE_LIST:
20349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                mDecorToolbar.setDropdownSelectedPosition(position);
20449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                break;
20549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            default:
20649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                throw new IllegalStateException(
20749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                        "setSelectedNavigationIndex not valid for current navigation mode");
20849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
20949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
21049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
21149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
21249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public int getSelectedNavigationIndex() {
21349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return -1;
21449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
21549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
21649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
21749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public int getNavigationItemCount() {
21849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return 0;
21949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
22049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
22149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
22249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setTitle(CharSequence title) {
22349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setTitle(title);
22449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
22549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
22649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
22749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setTitle(int resId) {
22849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setTitle(resId != 0 ? mDecorToolbar.getContext().getText(resId) : null);
22949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
23049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
23149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
232ca58f2ce7cd9f0e0f2c4a46c3bcc98013209f6b3Chris Banes    public void setWindowTitle(CharSequence title) {
233ca58f2ce7cd9f0e0f2c4a46c3bcc98013209f6b3Chris Banes        mDecorToolbar.setWindowTitle(title);
234ca58f2ce7cd9f0e0f2c4a46c3bcc98013209f6b3Chris Banes    }
235ca58f2ce7cd9f0e0f2c4a46c3bcc98013209f6b3Chris Banes
236ca58f2ce7cd9f0e0f2c4a46c3bcc98013209f6b3Chris Banes    @Override
237a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount    public boolean requestFocus() {
238a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount        final ViewGroup viewGroup = mDecorToolbar.getViewGroup();
239a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount        if (viewGroup != null && !viewGroup.hasFocus()) {
240a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount            viewGroup.requestFocus();
241a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount            return true;
242a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount        }
243a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount        return false;
244a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount    }
245a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount
246a6d085f83e2aec7ebda1fbbc69a5fd63c5f2e235George Mount    @Override
24749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setSubtitle(CharSequence subtitle) {
24849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setSubtitle(subtitle);
24949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
25049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
25149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
25249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setSubtitle(int resId) {
25349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setSubtitle(resId != 0 ? mDecorToolbar.getContext().getText(resId) : null);
25449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
25549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
25649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
25749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDisplayOptions(@DisplayOptions int options) {
25849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        setDisplayOptions(options, 0xffffffff);
25949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
26049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
26149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
26249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) {
263ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes        final int currentOptions = mDecorToolbar.getDisplayOptions();
264ac00a989afc2f1c559fc33174f481a0a0ef5b3d8Chris Banes        mDecorToolbar.setDisplayOptions(options & mask | currentOptions & ~mask);
26549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
26649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
26749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
26849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDisplayUseLogoEnabled(boolean useLogo) {
26949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        setDisplayOptions(useLogo ? DISPLAY_USE_LOGO : 0, DISPLAY_USE_LOGO);
27049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
27149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
27249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
27349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDisplayShowHomeEnabled(boolean showHome) {
27449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        setDisplayOptions(showHome ? DISPLAY_SHOW_HOME : 0, DISPLAY_SHOW_HOME);
27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
27649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
27749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
27849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
27949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        setDisplayOptions(showHomeAsUp ? DISPLAY_HOME_AS_UP : 0, DISPLAY_HOME_AS_UP);
28049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
28149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
28249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
28349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDisplayShowTitleEnabled(boolean showTitle) {
28449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        setDisplayOptions(showTitle ? DISPLAY_SHOW_TITLE : 0, DISPLAY_SHOW_TITLE);
28549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
28649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
28749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
28849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setDisplayShowCustomEnabled(boolean showCustom) {
28949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        setDisplayOptions(showCustom ? DISPLAY_SHOW_CUSTOM : 0, DISPLAY_SHOW_CUSTOM);
29049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
29149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
29249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
29349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setBackgroundDrawable(@Nullable Drawable d) {
2946aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        mDecorToolbar.setBackgroundDrawable(d);
29549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
29649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
29749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
29849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public View getCustomView() {
29949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return mDecorToolbar.getCustomView();
30049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
30149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
30249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
30349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public CharSequence getTitle() {
3046aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return mDecorToolbar.getTitle();
30549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
30649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
30749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
30849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public CharSequence getSubtitle() {
3096aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return mDecorToolbar.getSubtitle();
31049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
31149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
31249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
31349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public int getNavigationMode() {
31449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return NAVIGATION_MODE_STANDARD;
31549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
31649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
31749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
31849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void setNavigationMode(@NavigationMode int mode) {
31949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mode == ActionBar.NAVIGATION_MODE_TABS) {
32049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            throw new IllegalArgumentException("Tabs not supported in this configuration");
32149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
32249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mDecorToolbar.setNavigationMode(mode);
32349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
32449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
32549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
32649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public int getDisplayOptions() {
32749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return mDecorToolbar.getDisplayOptions();
32849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
32949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
33049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
33149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public Tab newTab() {
33249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
33349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
33449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
33549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
33649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
33749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void addTab(Tab tab) {
33849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
33949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
34049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
34149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
34249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
34349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void addTab(Tab tab, boolean setSelected) {
34449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
34549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
34649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
34749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
34849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
34949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void addTab(Tab tab, int position) {
35049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
35149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
35249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
35349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
35449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
35549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void addTab(Tab tab, int position, boolean setSelected) {
35649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
35749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
35849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
35949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
36049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
36149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void removeTab(Tab tab) {
36249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
36349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
36449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
36549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
36649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
36749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void removeTabAt(int position) {
36849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
36949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
37049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
37149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
37249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
37349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void removeAllTabs() {
37449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
37549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
37649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
37749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
37849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
37949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void selectTab(Tab tab) {
38049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
38149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
38249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
38349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
38449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
38549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public Tab getSelectedTab() {
38649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
38749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
38849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
38949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
39049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
39149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public Tab getTabAt(int index) {
39249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        throw new UnsupportedOperationException(
39349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                "Tabs are not supported in toolbar action bars");
39449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
39549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
39649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
39749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public int getTabCount() {
39849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return 0;
39949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
40049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
40149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
40249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public int getHeight() {
4036aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return mDecorToolbar.getHeight();
40449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
40549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
40649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
40749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void show() {
40849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // TODO: Consider a better transition for this.
40949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // Right now use no automatic transition so that the app can supply one if desired.
4106aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        mDecorToolbar.setVisibility(View.VISIBLE);
41149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
41249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
41349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
41449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void hide() {
41549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // TODO: Consider a better transition for this.
41649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        // Right now use no automatic transition so that the app can supply one if desired.
4176aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        mDecorToolbar.setVisibility(View.GONE);
41849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
41949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
42049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
42149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean isShowing() {
4226aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return mDecorToolbar.getVisibility() == View.VISIBLE;
42349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
42449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
42549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
42649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean openOptionsMenu() {
4276aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return mDecorToolbar.showOverflowMenu();
42849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
42949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
43049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
43149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean invalidateOptionsMenu() {
4326aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        mDecorToolbar.getViewGroup().removeCallbacks(mMenuInvalidator);
4336aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        ViewCompat.postOnAnimation(mDecorToolbar.getViewGroup(), mMenuInvalidator);
43449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return true;
43549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
43649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
43749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
43849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean collapseActionView() {
4396aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        if (mDecorToolbar.hasExpandedActionView()) {
4406aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar            mDecorToolbar.collapseActionView();
44149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            return true;
44249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
44349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return false;
44449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
44549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
44649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    void populateOptionsMenu() {
4470b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes        final Menu menu = getMenu();
44849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        final MenuBuilder mb = menu instanceof MenuBuilder ? (MenuBuilder) menu : null;
44949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mb != null) {
45049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mb.stopDispatchingItemsChanged();
45149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
45249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        try {
45349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            menu.clear();
45449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (!mWindowCallback.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu) ||
45549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                    !mWindowCallback.onPreparePanel(Window.FEATURE_OPTIONS_PANEL, null, menu)) {
45649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                menu.clear();
45749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
45849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        } finally {
45949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (mb != null) {
46049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                mb.startDispatchingItemsChanged();
46149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
46249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
46349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
46449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
46549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    @Override
46649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean onMenuKeyEvent(KeyEvent event) {
46749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (event.getAction() == KeyEvent.ACTION_UP) {
46849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            openOptionsMenu();
46949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
47049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return true;
47149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
47249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
473d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes    @Override
474d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes    public boolean onKeyShortcut(int keyCode, KeyEvent ev) {
475d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes        Menu menu = getMenu();
4769efaee2e7e3a147405847736eacdb5e1c66ae1c2Chris Banes        if (menu != null) {
4779d9c6a22548670bf017e69fd5d0f47134a18b53fChris Banes            final KeyCharacterMap kmap = KeyCharacterMap.load(
4789d9c6a22548670bf017e69fd5d0f47134a18b53fChris Banes                    ev != null ? ev.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
4799d9c6a22548670bf017e69fd5d0f47134a18b53fChris Banes            menu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC);
4809efaee2e7e3a147405847736eacdb5e1c66ae1c2Chris Banes            menu.performShortcut(keyCode, ev, 0);
4819efaee2e7e3a147405847736eacdb5e1c66ae1c2Chris Banes        }
4829efaee2e7e3a147405847736eacdb5e1c66ae1c2Chris Banes        // This action bar always returns true for handling keyboard shortcuts.
4839efaee2e7e3a147405847736eacdb5e1c66ae1c2Chris Banes        // This will block the window from preparing a temporary panel to handle
4849efaee2e7e3a147405847736eacdb5e1c66ae1c2Chris Banes        // keyboard shortcuts.
4859efaee2e7e3a147405847736eacdb5e1c66ae1c2Chris Banes        return true;
486d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes    }
487d15ee7df01f2f48b536a610c4739f33b226d3f81Chris Banes
488733d0b2acb07ede7455b9d020901a10586053923Chris Banes    @Override
489733d0b2acb07ede7455b9d020901a10586053923Chris Banes    void onDestroy() {
490733d0b2acb07ede7455b9d020901a10586053923Chris Banes        // Remove any invalidation callbacks
491733d0b2acb07ede7455b9d020901a10586053923Chris Banes        mDecorToolbar.getViewGroup().removeCallbacks(mMenuInvalidator);
492733d0b2acb07ede7455b9d020901a10586053923Chris Banes    }
493733d0b2acb07ede7455b9d020901a10586053923Chris Banes
49449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void addOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
49549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mMenuVisibilityListeners.add(listener);
49649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
49749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
49849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void removeOnMenuVisibilityListener(OnMenuVisibilityListener listener) {
49949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mMenuVisibilityListeners.remove(listener);
50049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
50149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
50249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public void dispatchMenuVisibilityChanged(boolean isVisible) {
50349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (isVisible == mLastMenuVisibility) {
50449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            return;
50549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
50649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        mLastMenuVisibility = isVisible;
50749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
50849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        final int count = mMenuVisibilityListeners.size();
50949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        for (int i = 0; i < count; i++) {
51049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mMenuVisibilityListeners.get(i).onMenuVisibilityChanged(isVisible);
51149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
51249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
5130b216f2263135782c361e122892a12156d5d2ce1Chris Banes
5142c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas    View getListMenuView(Menu menu) {
51546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        ensureListMenuPresenter(menu);
51646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
517da0b9d63d6f940cbfd5b526c3f81858aeadcb7e8Chris Banes        if (menu == null || mListMenuPresenter == null) {
51857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            return null;
51957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        }
52057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
52157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        if (mListMenuPresenter.getAdapter().getCount() > 0) {
5226aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar            return (View) mListMenuPresenter.getMenuView(mDecorToolbar.getViewGroup());
52357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        }
52457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        return null;
52557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes    }
52657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
52746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    private void ensureListMenuPresenter(Menu menu) {
52846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        if (mListMenuPresenter == null && (menu instanceof MenuBuilder)) {
52946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            MenuBuilder mb = (MenuBuilder) menu;
53046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
53146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            Context context = mDecorToolbar.getContext();
53246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            final TypedValue outValue = new TypedValue();
53346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            final Resources.Theme widgetTheme = context.getResources().newTheme();
53446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            widgetTheme.setTo(context.getTheme());
53546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
536ceacdb3af2ceaaded8d27e0393483a7eef59aa17Chris Banes            // First apply the actionBarPopupTheme
537ceacdb3af2ceaaded8d27e0393483a7eef59aa17Chris Banes            widgetTheme.resolveAttribute(R.attr.actionBarPopupTheme, outValue, true);
538ceacdb3af2ceaaded8d27e0393483a7eef59aa17Chris Banes            if (outValue.resourceId != 0) {
539ceacdb3af2ceaaded8d27e0393483a7eef59aa17Chris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
540ceacdb3af2ceaaded8d27e0393483a7eef59aa17Chris Banes            }
541ceacdb3af2ceaaded8d27e0393483a7eef59aa17Chris Banes
54246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // Apply the panelMenuListTheme
54346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            widgetTheme.resolveAttribute(R.attr.panelMenuListTheme, outValue, true);
54446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            if (outValue.resourceId != 0) {
54546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                widgetTheme.applyStyle(outValue.resourceId, true);
54646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            } else {
54746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                widgetTheme.applyStyle(R.style.Theme_AppCompat_CompactMenu, true);
54846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            }
54946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
55046dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            context = new ContextThemeWrapper(context, 0);
55146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            context.getTheme().setTo(widgetTheme);
55246dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
55346dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            // Finally create the list menu presenter
55446dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            mListMenuPresenter = new ListMenuPresenter(context, R.layout.abc_list_menu_item_layout);
55546dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            mListMenuPresenter.setCallback(new PanelMenuPresenterCallback());
55646dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes            mb.addMenuPresenter(mListMenuPresenter);
55746dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes        }
55846dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes    }
55946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes
5600b216f2263135782c361e122892a12156d5d2ce1Chris Banes    private class ToolbarCallbackWrapper extends WindowCallbackWrapper {
561f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes        public ToolbarCallbackWrapper(Window.Callback wrapped) {
5620b216f2263135782c361e122892a12156d5d2ce1Chris Banes            super(wrapped);
5630b216f2263135782c361e122892a12156d5d2ce1Chris Banes        }
5640b216f2263135782c361e122892a12156d5d2ce1Chris Banes
5650b216f2263135782c361e122892a12156d5d2ce1Chris Banes        @Override
5660b216f2263135782c361e122892a12156d5d2ce1Chris Banes        public boolean onPreparePanel(int featureId, View view, Menu menu) {
5670b216f2263135782c361e122892a12156d5d2ce1Chris Banes            final boolean result = super.onPreparePanel(featureId, view, menu);
5680b216f2263135782c361e122892a12156d5d2ce1Chris Banes            if (result && !mToolbarMenuPrepared) {
5690b216f2263135782c361e122892a12156d5d2ce1Chris Banes                mDecorToolbar.setMenuPrepared();
5700b216f2263135782c361e122892a12156d5d2ce1Chris Banes                mToolbarMenuPrepared = true;
5710b216f2263135782c361e122892a12156d5d2ce1Chris Banes            }
5720b216f2263135782c361e122892a12156d5d2ce1Chris Banes            return result;
5730b216f2263135782c361e122892a12156d5d2ce1Chris Banes        }
57457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
57557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        @Override
57657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        public View onCreatePanelView(int featureId) {
57757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            switch (featureId) {
57857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                case Window.FEATURE_OPTIONS_PANEL:
57946dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                    final Menu menu = mDecorToolbar.getMenu();
580f3ad1351d8b40ec5defe35e79d3430ad3c384b6dChris Banes                    if (onPreparePanel(featureId, null, menu) && onMenuOpened(featureId, menu)) {
58146dfe0c53492ef0cb59873123ca141906fbb7dccChris Banes                        return getListMenuView(menu);
58257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                    }
58357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                    break;
58457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
58557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            return super.onCreatePanelView(featureId);
58657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        }
5870b216f2263135782c361e122892a12156d5d2ce1Chris Banes    }
588c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
5890b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes    private Menu getMenu() {
5900b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes        if (!mMenuCallbackSet) {
5916aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar            mDecorToolbar.setMenuCallbacks(new ActionMenuPresenterCallback(),
5926aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar                    new MenuBuilderCallback());
5930b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes            mMenuCallbackSet = true;
5940b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes        }
5956aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar        return mDecorToolbar.getMenu();
5960b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes    }
5970b7aedbbe43b9d4af60cc4ebd4994c74ebe6bc5fChris Banes
598c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
599c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        private boolean mClosingActionMenu;
600c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
6012c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas        ActionMenuPresenterCallback() {
6022c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas        }
6032c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas
604c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        @Override
605c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
606c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            if (mWindowCallback != null) {
607d25af35061a9f20d59b25329d613c62c20184dadChris Banes                mWindowCallback.onMenuOpened(AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR, subMenu);
608c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes                return true;
609c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            }
610c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            return false;
611c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
612c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
613c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        @Override
614c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
615c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            if (mClosingActionMenu) {
616c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes                return;
617c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            }
618c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
619c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            mClosingActionMenu = true;
6206aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar            mDecorToolbar.dismissPopupMenus();
621c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            if (mWindowCallback != null) {
622d25af35061a9f20d59b25329d613c62c20184dadChris Banes                mWindowCallback.onPanelClosed(AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR, menu);
623c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            }
624c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            mClosingActionMenu = false;
625c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
626c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    }
627c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
62857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes    private final class PanelMenuPresenterCallback implements MenuPresenter.Callback {
6292c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas        PanelMenuPresenterCallback() {
6302c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas        }
6312c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas
63257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        @Override
63357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
63457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (mWindowCallback != null) {
63557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                mWindowCallback.onPanelClosed(Window.FEATURE_OPTIONS_PANEL, menu);
63657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
63757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        }
63857c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
63957c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        @Override
64057c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        public boolean onOpenSubMenu(MenuBuilder subMenu) {
64157c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            if (subMenu == null && mWindowCallback != null) {
64257c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes                mWindowCallback.onMenuOpened(Window.FEATURE_OPTIONS_PANEL, subMenu);
64357c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            }
64457c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes            return true;
64557c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes        }
64657c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes    }
64757c6de90985a63358129b99b9f0cd4d6afe887d6Chris Banes
648c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    private final class MenuBuilderCallback implements MenuBuilder.Callback {
649c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
6502c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas        MenuBuilderCallback() {
6512c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas        }
6522c1bad7ecd5879bf0f29ce2ce1bc5bd67a3f4682Aurimas Liutikas
653c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        @Override
654c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
655c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            return false;
656c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
657c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes
658c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        @Override
659c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        public void onMenuModeChange(MenuBuilder menu) {
660c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            if (mWindowCallback != null) {
6616aadbd39814a5ae41e1fadfab06657cdf901e625Yigit Boyar                if (mDecorToolbar.isOverflowMenuShowing()) {
662d25af35061a9f20d59b25329d613c62c20184dadChris Banes                    mWindowCallback.onPanelClosed(AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR, menu);
663c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes                } else if (mWindowCallback.onPreparePanel(Window.FEATURE_OPTIONS_PANEL,
664c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes                        null, menu)) {
665d25af35061a9f20d59b25329d613c62c20184dadChris Banes                    mWindowCallback.onMenuOpened(AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR, menu);
666c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes                }
667c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes            }
668c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes        }
669c4b9e0cb716a4caff218b27d86f37ef8117d257bChris Banes    }
6700b216f2263135782c361e122892a12156d5d2ce1Chris Banes}
671