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 */
16da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownpackage android.support.v7.internal.widget;
17bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
18bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.Context;
19bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.Configuration;
20bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.content.res.TypedArray;
2134b5c9580dd01b4428ab2c5990add571eaab6b13Trevor Johnsimport android.os.Build;
22da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.appcompat.R;
23da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.internal.view.menu.ActionMenuPresenter;
24da10fdd1400ecfd8d7f2e55651dd528d0614dfc5Jeff Brownimport android.support.v7.internal.view.menu.ActionMenuView;
25bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.util.AttributeSet;
26bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.View;
27bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powellimport android.view.ViewGroup;
289addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banesimport android.view.animation.Animation;
299addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banesimport android.view.animation.AnimationUtils;
30bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
3179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banesabstract class AbsActionBarView extends ViewGroup {
32bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
3320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected ActionMenuView mMenuView;
34bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
3520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected ActionMenuPresenter mActionMenuPresenter;
36bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
3720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected ActionBarContainer mSplitView;
38bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
3920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected boolean mSplitActionBar;
4020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
4120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected boolean mSplitWhenNarrow;
4220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
4320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected int mContentHeight;
4420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
4520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    private static final int FADE_DURATION = 200;
4620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
4779e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    AbsActionBarView(Context context) {
4820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super(context);
4920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
5020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
5179e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    AbsActionBarView(Context context, AttributeSet attrs) {
5220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super(context, attrs);
5320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
5420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
5579e7a9ef79920c7daa10c90339db126a4c3c592eChris Banes    AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
5620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        super(context, attrs, defStyle);
5720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
5820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
5920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
6020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected void onConfigurationChanged(Configuration newConfig) {
6120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (Build.VERSION.SDK_INT >= 8) {
6220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            super.onConfigurationChanged(newConfig);
6320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
6420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
6520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Action bar can change size on configuration changes.
6620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        // Reread the desired height from the theme-specified style.
6720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar,
6820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                R.attr.actionBarStyle, 0);
6920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0));
7020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        a.recycle();
7120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mSplitWhenNarrow) {
7220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            setSplitActionBar(getContext().getResources().getBoolean(
7307a07ce59efb770e9fb9ca53a0133e5e64a63bbcChris Banes                    R.bool.abc_split_action_bar_is_narrow));
7420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
7520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
7620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mActionMenuPresenter.onConfigurationChanged(newConfig);
7720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
7820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
7920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
8020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
8120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Sets whether the bar should be split right now, no questions asked.
8220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *
8320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param split true if the bar should split
8420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
8520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setSplitActionBar(boolean split) {
8620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mSplitActionBar = split;
8720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
8820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
8920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
9020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * Sets whether the bar should split if we enter a narrow screen configuration.
9120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     *
9220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @param splitWhenNarrow true if the bar should check to split after a config change
9320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
9420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setSplitWhenNarrow(boolean splitWhenNarrow) {
9520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mSplitWhenNarrow = splitWhenNarrow;
9620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
9720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
9820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setContentHeight(int height) {
9920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mContentHeight = height;
10020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        requestLayout();
10120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
10220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
10320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public int getContentHeight() {
10420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return mContentHeight;
10520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
10620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
10720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setSplitView(ActionBarContainer splitView) {
10820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        mSplitView = splitView;
10920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
11020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
11120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    /**
11220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     * @return Current visibility or if animating, the visibility being animated to.
11320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns     */
11420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public int getAnimatedVisibility() {
11520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return getVisibility();
11620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
11720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
11820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void animateToVisibility(int visibility) {
1199addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes        clearAnimation();
1209addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes
1219addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes        if (visibility != getVisibility()) {
1229addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            Animation anim = AnimationUtils.loadAnimation(getContext(),
1239addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes                    visibility == View.VISIBLE ? R.anim.abc_fade_in : R.anim.abc_fade_out);
1249addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes
1259addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            startAnimation(anim);
1269addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            setVisibility(visibility);
1279addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes
1289addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            if (mSplitView != null && mMenuView != null) {
1299addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes                mMenuView.startAnimation(anim);
1309addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes                mMenuView.setVisibility(visibility);
1319addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes            }
1329addcff1698f71fb4145f39dacaf33a9c1fef24fChris Banes        }
13320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
13420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
13520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    @Override
13620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void setVisibility(int visibility) {
13720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (visibility != getVisibility()) {
13820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            super.setVisibility(visibility);
13920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
14020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
14120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean showOverflowMenu() {
14320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
14420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return mActionMenuPresenter.showOverflowMenu();
14520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
14620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
14720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
14820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
14920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void postShowOverflowMenu() {
15020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        post(new Runnable() {
15120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            public void run() {
15220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                showOverflowMenu();
15320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            }
15420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        });
15520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
15620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
15720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean hideOverflowMenu() {
15820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
15920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return mActionMenuPresenter.hideOverflowMenu();
16020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
16120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
16220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
16320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
16420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean isOverflowMenuShowing() {
16520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
16620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            return mActionMenuPresenter.isOverflowMenuShowing();
16720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
16820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return false;
16920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
17020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
17120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public boolean isOverflowReserved() {
17220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return mActionMenuPresenter != null && mActionMenuPresenter.isOverflowReserved();
17320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
17420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
17520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    public void dismissPopupMenus() {
17620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        if (mActionMenuPresenter != null) {
17720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            mActionMenuPresenter.dismissPopupMenus();
17820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        }
17920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
18020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
18120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected int measureChildView(View child, int availableWidth, int childSpecHeight,
18220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns            int spacing) {
18320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        child.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
18420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns                childSpecHeight);
18520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
18620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        availableWidth -= child.getMeasuredWidth();
18720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        availableWidth -= spacing;
18820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
18920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return Math.max(0, availableWidth);
19020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
19120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
19220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected int positionChild(View child, int x, int y, int contentHeight) {
19320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childWidth = child.getMeasuredWidth();
19420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childHeight = child.getMeasuredHeight();
19520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childTop = y + (contentHeight - childHeight) / 2;
19620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
19720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        child.layout(x, childTop, x + childWidth, childTop + childHeight);
19820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
19920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return childWidth;
20020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
20120ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
20220ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    protected int positionChildInverse(View child, int x, int y, int contentHeight) {
20320ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childWidth = child.getMeasuredWidth();
20420ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childHeight = child.getMeasuredHeight();
20520ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        int childTop = y + (contentHeight - childHeight) / 2;
20620ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
20720ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        child.layout(x - childWidth, childTop, x, childTop + childHeight);
20820ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns
20920ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns        return childWidth;
21020ac724a3a836bfd362c911f7dc55a61c02b4d44Trevor Johns    }
211bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell
212bbbb8f39d1b1d1b317c5f9237f20fe6b1d9eb17fAdam Powell}
213