1bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell/*
2bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Copyright (C) 2011 The Android Open Source Project
3bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
4bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * you may not use this file except in compliance with the License.
6bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * You may obtain a copy of the License at
7bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
8bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell *
10bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * Unless required by applicable law or agreed to in writing, software
11bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * See the License for the specific language governing permissions and
14bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell * limitations under the License.
15bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell */
16acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.appcompat.widget;
18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
19bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context;
20bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Configuration;
21bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.TypedArray;
22bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.AttributeSet;
2349c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.util.TypedValue;
2449c78900da0d43140fb602431fb93212bd7f6c70Chris Banesimport android.view.ContextThemeWrapper;
2546be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banesimport android.view.MotionEvent;
26bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View;
27bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewGroup;
28bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
293de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.appcompat.R;
303de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.core.view.ViewCompat;
313de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.core.view.ViewPropertyAnimatorCompat;
323de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikasimport androidx.core.view.ViewPropertyAnimatorListener;
333de8a4e8305507475d7890205184946a25cf45e7Aurimas Liutikas
3479e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesabstract class AbsActionBarView extends ViewGroup {
3549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    private static final int FADE_DURATION = 200;
36bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
3749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    protected final VisibilityAnimListener mVisAnimListener = new VisibilityAnimListener();
38bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
3949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    /** Context against which to inflate popup menus. */
4049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    protected final Context mPopupContext;
41bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
4249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    protected ActionMenuView mMenuView;
4349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    protected ActionMenuPresenter mActionMenuPresenter;
4420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected int mContentHeight;
4520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
4649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    protected ViewPropertyAnimatorCompat mVisibilityAnim;
4720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
4846be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    private boolean mEatingTouch;
4946be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    private boolean mEatingHover;
5046be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
5179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    AbsActionBarView(Context context) {
5249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        this(context, null);
5320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
5420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
5579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    AbsActionBarView(Context context, AttributeSet attrs) {
5649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        this(context, attrs, 0);
5720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
5820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
5979e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super(context, attrs, defStyle);
6149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
6249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        final TypedValue tv = new TypedValue();
6349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (context.getTheme().resolveAttribute(R.attr.actionBarPopupTheme, tv, true)
6449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                && tv.resourceId != 0) {
6549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mPopupContext = new ContextThemeWrapper(context, tv.resourceId);
6649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        } else {
6749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mPopupContext = context;
6849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
6920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
7020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
7120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
7220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected void onConfigurationChanged(Configuration newConfig) {
7364dbe1d454f1190b3cd8426d09b9119949a10709Kirill Grouchnikov        super.onConfigurationChanged(newConfig);
7420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
7520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Action bar can change size on configuration changes.
7620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Reread the desired height from the theme-specified style.
7720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar,
7820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                R.attr.actionBarStyle, 0);
7920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
8020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        a.recycle();
8149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
8220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
8320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mActionMenuPresenter.onConfigurationChanged(newConfig);
8420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
8520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
8620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
8746be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    @Override
8846be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    public boolean onTouchEvent(MotionEvent ev) {
8946be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        // ActionBarViews always eat touch events, but should still respect the touch event dispatch
9046be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        // contract. If the normal View implementation doesn't want the events, we'll just silently
9146be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        // eat the rest of the gesture without reporting the events to the default implementation
9246be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        // since that's what it expects.
9346be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
946ed40c1f86bcb172a1f0f069cde1c571a7781aeeAurimas Liutikas        final int action = ev.getActionMasked();
9546be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        if (action == MotionEvent.ACTION_DOWN) {
9646be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            mEatingTouch = false;
9746be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        }
9846be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
9946be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        if (!mEatingTouch) {
10046be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            final boolean handled = super.onTouchEvent(ev);
10146be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            if (action == MotionEvent.ACTION_DOWN && !handled) {
10246be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes                mEatingTouch = true;
10346be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            }
10446be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        }
10546be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
10646be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
10746be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            mEatingTouch = false;
10846be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        }
10946be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
11046be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        return true;
11146be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    }
11246be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
11346be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    @Override
11446be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    public boolean onHoverEvent(MotionEvent ev) {
11546be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        // Same deal as onTouchEvent() above. Eat all hover events, but still
11646be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        // respect the touch event dispatch contract.
11746be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
1186ed40c1f86bcb172a1f0f069cde1c571a7781aeeAurimas Liutikas        final int action = ev.getActionMasked();
1196ed40c1f86bcb172a1f0f069cde1c571a7781aeeAurimas Liutikas        if (action == MotionEvent.ACTION_HOVER_ENTER) {
12046be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            mEatingHover = false;
12146be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        }
12246be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
12346be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        if (!mEatingHover) {
12446be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            final boolean handled = super.onHoverEvent(ev);
1256ed40c1f86bcb172a1f0f069cde1c571a7781aeeAurimas Liutikas            if (action == MotionEvent.ACTION_HOVER_ENTER && !handled) {
12646be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes                mEatingHover = true;
12746be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            }
12846be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        }
12946be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
1306ed40c1f86bcb172a1f0f069cde1c571a7781aeeAurimas Liutikas        if (action == MotionEvent.ACTION_HOVER_EXIT
13146be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes                || action == MotionEvent.ACTION_CANCEL) {
13246be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes            mEatingHover = false;
13346be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        }
13446be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
13546be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes        return true;
13646be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes    }
13746be6a08e9d1b4b989f74f800b71a1221321ab6eChris Banes
13820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setContentHeight(int height) {
13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mContentHeight = height;
14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        requestLayout();
14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
14220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public int getContentHeight() {
14420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return mContentHeight;
14520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return Current visibility or if animating, the visibility being animated to.
14920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
15020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public int getAnimatedVisibility() {
15149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mVisibilityAnim != null) {
15249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            return mVisAnimListener.mFinalVisibility;
15349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
15420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return getVisibility();
15520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
15620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
157acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes    public ViewPropertyAnimatorCompat setupAnimatorToVisibility(int visibility, long duration) {
15849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mVisibilityAnim != null) {
15949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mVisibilityAnim.cancel();
16049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
161acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes
16249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (visibility == VISIBLE) {
16349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (getVisibility() != VISIBLE) {
164fa0f82f629bf95681c14ed559922f77a3030aa18Aurimas Liutikas                setAlpha(0f);
16549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            }
16649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ViewPropertyAnimatorCompat anim = ViewCompat.animate(this).alpha(1f);
167acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            anim.setDuration(duration);
168acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            anim.setListener(mVisAnimListener.withFinalVisibility(anim, visibility));
169acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            return anim;
17049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        } else {
17149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            ViewPropertyAnimatorCompat anim = ViewCompat.animate(this).alpha(0f);
172acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            anim.setDuration(duration);
173acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            anim.setListener(mVisAnimListener.withFinalVisibility(anim, visibility));
174acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            return anim;
175acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes        }
176acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes    }
177acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes
178acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes    public void animateToVisibility(int visibility) {
179acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes        ViewPropertyAnimatorCompat anim = setupAnimatorToVisibility(visibility, FADE_DURATION);
180acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes        anim.start();
181acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes    }
182acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes
183acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes    @Override
184acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes    public void setVisibility(int visibility) {
185acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes        if (visibility != getVisibility()) {
186acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            if (mVisibilityAnim != null) {
187acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes                mVisibilityAnim.cancel();
1889addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            }
189acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            super.setVisibility(visibility);
1909addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes        }
19120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
19220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
19320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean showOverflowMenu() {
19420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
19520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return mActionMenuPresenter.showOverflowMenu();
19620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
19720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
19820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
19920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
20020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void postShowOverflowMenu() {
20120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        post(new Runnable() {
202e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas            @Override
20320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            public void run() {
20420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                showOverflowMenu();
20520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
20620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        });
20720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
20820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
20920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean hideOverflowMenu() {
21020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
21120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return mActionMenuPresenter.hideOverflowMenu();
21220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
21320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
21420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
21520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
21620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean isOverflowMenuShowing() {
21720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
21820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return mActionMenuPresenter.isOverflowMenuShowing();
21920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
22020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
22120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
22220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
22349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean isOverflowMenuShowPending() {
22449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (mActionMenuPresenter != null) {
22549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            return mActionMenuPresenter.isOverflowMenuShowPending();
22649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
22749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return false;
22849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
22949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
23020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean isOverflowReserved() {
23120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
23220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
23320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
23449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    public boolean canShowOverflowMenu() {
23549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return isOverflowReserved() && getVisibility() == VISIBLE;
23649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
23749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
23820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void dismissPopupMenus() {
23920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
24020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mActionMenuPresenter.dismissPopupMenus();
24120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
24220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
24320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
24420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected int measureChildView(View child, int availableWidth, int childSpecHeight,
24520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            int spacing) {
24620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
24720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                childSpecHeight);
24820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
24920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        availableWidth -= child.getMeasuredWidth();
25020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        availableWidth -= spacing;
25120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
25220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return Math.max(0, availableWidth);
25320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
25420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
25549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    static protected int next(int x, int val, boolean isRtl) {
25649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return isRtl ? x - val : x + val;
25749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
25849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
25949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    protected int positionChild(View child, int x, int y, int contentHeight, boolean reverse) {
26020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childWidth = child.getMeasuredWidth();
26120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childHeight = child.getMeasuredHeight();
26220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childTop = y + (contentHeight - childHeight) / 2;
26320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
26449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        if (reverse) {
26549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            child.layout(x - childWidth, childTop, x, childTop + childHeight);
26649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        } else {
26749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            child.layout(x, childTop, x + childWidth, childTop + childHeight);
26849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
26920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
27049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        return  (reverse ? -childWidth : childWidth);
27120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
27220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
27349c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    protected class VisibilityAnimListener implements ViewPropertyAnimatorListener {
27449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        private boolean mCanceled = false;
27549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        int mFinalVisibility;
27620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
27749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public VisibilityAnimListener withFinalVisibility(ViewPropertyAnimatorCompat animation,
27849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes                int visibility) {
27949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mVisibilityAnim = animation;
28049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mFinalVisibility = visibility;
28149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            return this;
28249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
28320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
28449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        @Override
28549c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public void onAnimationStart(View view) {
286acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            AbsActionBarView.super.setVisibility(VISIBLE);
28749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mCanceled = false;
28849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
28949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
29049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        @Override
29149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public void onAnimationEnd(View view) {
29249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            if (mCanceled) return;
293bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
29449c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mVisibilityAnim = null;
295acce58688e2c3e5abd0b13e78dcf2c26710eabd0Chris Banes            AbsActionBarView.super.setVisibility(mFinalVisibility);
29649c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
29749c78900da0d43140fb602431fb93212bd7f6c70Chris Banes
29849c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        @Override
29949c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        public void onAnimationCancel(View view) {
30049c78900da0d43140fb602431fb93212bd7f6c70Chris Banes            mCanceled = true;
30149c78900da0d43140fb602431fb93212bd7f6c70Chris Banes        }
30249c78900da0d43140fb602431fb93212bd7f6c70Chris Banes    }
303bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell}
304