182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague/*
282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * Copyright (C) 2014 The Android Open Source Project
382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague *
482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * Licensed under the Apache License, Version 2.0 (the "License");
582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * you may not use this file except in compliance with the License.
682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * You may obtain a copy of the License at
782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague *
882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague *      http://www.apache.org/licenses/LICENSE-2.0
982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague *
1082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * Unless required by applicable law or agreed to in writing, software
1182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * distributed under the License is distributed on an "AS IS" BASIS,
1282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * See the License for the specific language governing permissions and
1482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague * limitations under the License.
1582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague */
1682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spraguepackage com.android.camera.widget;
1782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
1882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.Animator;
1982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.AnimatorListenerAdapter;
2082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.AnimatorSet;
2182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.animation.ValueAnimator;
2282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.content.Context;
2382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.content.res.Configuration;
2482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.graphics.Canvas;
2582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.graphics.Paint;
2682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.graphics.RectF;
2718b22b5963e8871e539edf669d96862eec72bb5dSpike Spragueimport android.util.AttributeSet;
2882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.view.View;
2956d43cf80d40379d57ac1db697bc014d5c321b91Spike Spragueimport android.view.ViewGroup;
3082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport android.widget.FrameLayout;
31abf54e2994961395a0feb0b08353e62718443f23Spike Spragueimport android.widget.ImageButton;
3282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
3318b22b5963e8871e539edf669d96862eec72bb5dSpike Spragueimport com.android.camera.MultiToggleImageButton;
3459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Spragueimport com.android.camera.ui.RadioOptions;
3556d43cf80d40379d57ac1db697bc014d5c321b91Spike Spragueimport com.android.camera.ui.TopRightWeightedLayout;
3682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport com.android.camera.util.Gusterpolator;
3782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spragueimport com.android.camera2.R;
3882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
3956d43cf80d40379d57ac1db697bc014d5c321b91Spike Spragueimport java.util.ArrayList;
4056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague
4182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Spraguepublic class ModeOptions extends FrameLayout {
4282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private int mBackgroundColor;
4382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private final Paint mPaint = new Paint();
44591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague    private boolean mIsHiddenOrHiding;
4582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private RectF mAnimateFrom = new RectF();
4682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private View mViewToShowHide;
4756d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague    private TopRightWeightedLayout mModeOptionsButtons;
4859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private RadioOptions mModeOptionsPano;
4959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private RadioOptions mModeOptionsExposure;
5082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
5182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private AnimatorSet mVisibleAnimator;
5282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private AnimatorSet mHiddenAnimator;
5382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private boolean mDrawCircle;
5482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private boolean mFill;
5582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private static final int RADIUS_ANIMATION_TIME = 250;
5682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private static final int SHOW_ALPHA_ANIMATION_TIME = 350;
5782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private static final int HIDE_ALPHA_ANIMATION_TIME = 200;
5856d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague    private static final int PADDING_ANIMATION_TIME = 350;
5982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
6059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private ViewGroup mMainBar;
6159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    private ViewGroup mActiveBar;
6259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public static final int BAR_INVALID = -1;
6359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public static final int BAR_STANDARD = 0;
6459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public static final int BAR_PANO = 1;
6559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague
6682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private boolean mIsPortrait;
674df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu    private float mRadius = 0f;
6882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
6982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    public ModeOptions(Context context, AttributeSet attrs) {
7082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        super(context, attrs);
7182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
7282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
7382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    public void setViewToShowHide(View v) {
7482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        mViewToShowHide = v;
7582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
7682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
7782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    @Override
7882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    public void onFinishInflate() {
79591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague        mIsHiddenOrHiding = true;
8082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        mBackgroundColor = getResources().getColor(R.color.mode_options_background);
8182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        mPaint.setAntiAlias(true);
8282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        mPaint.setColor(mBackgroundColor);
8356d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague        mModeOptionsButtons = (TopRightWeightedLayout) findViewById(R.id.mode_options_buttons);
8459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptionsPano = (RadioOptions) findViewById(R.id.mode_options_pano);
8559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mModeOptionsExposure = (RadioOptions) findViewById(R.id.mode_options_exposure);
8659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mMainBar = mActiveBar = mModeOptionsButtons;
87abf54e2994961395a0feb0b08353e62718443f23Spike Sprague
88abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        ImageButton exposureButton = (ImageButton) findViewById(R.id.exposure_button);
89abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        exposureButton.setOnClickListener(new View.OnClickListener() {
90abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            @Override
91abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            public void onClick(View v) {
9259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mActiveBar = mModeOptionsExposure;
9359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mMainBar.setVisibility(View.INVISIBLE);
9459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mActiveBar.setVisibility(View.VISIBLE);
95abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            }
96abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        });
9782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
9882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
9959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public void setMainBar(int b) {
10059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        for (int i = 0; i < getChildCount(); i++) {
10159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            getChildAt(i).setVisibility(View.INVISIBLE);
10282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        }
10359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        switch (b) {
10459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        case BAR_STANDARD:
10559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            mMainBar = mActiveBar = mModeOptionsButtons;
10659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            break;
10759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        case BAR_PANO:
10859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            mMainBar = mActiveBar = mModeOptionsPano;
10959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            break;
11059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        }
11159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        mMainBar.setVisibility(View.VISIBLE);
11259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    }
11382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
11459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague    public int getMainBar() {
11559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        if (mMainBar == mModeOptionsButtons) {
11659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            return BAR_STANDARD;
11759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        }
11859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        if (mMainBar == mModeOptionsPano) {
11959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            return BAR_PANO;
12059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        }
12159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague        return BAR_INVALID;
12282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
12382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
124abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    @Override
125abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    public void onWindowVisibilityChanged(int visibility) {
126abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        super.onWindowVisibilityChanged(visibility);
127abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        if (visibility != VISIBLE && !mIsHiddenOrHiding) {
128abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            // Collapse mode options when window is not visible.
129abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            setVisibility(INVISIBLE);
13059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            if (mMainBar != null) {
13159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mMainBar.setVisibility(VISIBLE);
13259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            }
13359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            if (mActiveBar != null && mActiveBar != mMainBar) {
13459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                mActiveBar.setVisibility(INVISIBLE);
135abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            }
136abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            if (mViewToShowHide != null) {
137abf54e2994961395a0feb0b08353e62718443f23Spike Sprague                mViewToShowHide.setVisibility(VISIBLE);
138abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            }
139abf54e2994961395a0feb0b08353e62718443f23Spike Sprague            mIsHiddenOrHiding = true;
140abf54e2994961395a0feb0b08353e62718443f23Spike Sprague        }
141abf54e2994961395a0feb0b08353e62718443f23Spike Sprague    }
142abf54e2994961395a0feb0b08353e62718443f23Spike Sprague
14382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    @Override
14482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
14582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        if (changed) {
14682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            mIsPortrait = (getResources().getConfiguration().orientation ==
14782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                           Configuration.ORIENTATION_PORTRAIT);
14882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
14982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            int buttonSize = getResources()
15082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                .getDimensionPixelSize(R.dimen.option_button_circle_size);
15182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            int buttonPadding = getResources()
15282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                .getDimensionPixelSize(R.dimen.mode_options_toggle_padding);
15382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
15482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            float rLeft, rRight, rTop, rBottom;
15582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            if (mIsPortrait) {
15682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                rLeft = getWidth() - buttonPadding - buttonSize;
15782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                rTop = (getHeight() - buttonSize) / 2.0f;
15882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            } else {
15982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                rLeft = buttonPadding;
16082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                rTop = buttonPadding;
16182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            }
16282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            rRight = rLeft + buttonSize;
16382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            rBottom = rTop + buttonSize;
16482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            mAnimateFrom.set(rLeft, rTop, rRight, rBottom);
16582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
16682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            setupAnimators();
16718b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague            setupToggleButtonParams();
16882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        }
16982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
17082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        super.onLayout(changed, left, top, right, bottom);
17182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
17282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
17382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    @Override
17482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    public void onDraw(Canvas canvas) {
17582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        if (mDrawCircle) {
1764df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu            canvas.drawCircle(mAnimateFrom.centerX(), mAnimateFrom.centerY(), mRadius, mPaint);
17782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        } else if (mFill) {
17882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            canvas.drawPaint(mPaint);
17982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        }
18082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        super.onDraw(canvas);
18182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
18282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
18318b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague    private void setupToggleButtonParams() {
18418b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague        int size = (mIsPortrait ? getHeight() : getWidth());
18518b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague
18618b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague        for (int i = 0; i < mModeOptionsButtons.getChildCount(); i++) {
18718b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague            View button = mModeOptionsButtons.getChildAt(i);
18818b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague            if (button instanceof MultiToggleImageButton) {
18918b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague                MultiToggleImageButton toggleButton = (MultiToggleImageButton) button;
19018b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague                toggleButton.setParentSize(size);
19118b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague                toggleButton.setAnimDirection(mIsPortrait ?
19218b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague                        MultiToggleImageButton.ANIM_DIRECTION_VERTICAL :
19318b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague                        MultiToggleImageButton.ANIM_DIRECTION_HORIZONTAL);
19418b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague            }
19518b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague        }
19618b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague    }
19718b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague
19882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    private void setupAnimators() {
199fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague        if (mVisibleAnimator != null) {
200fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague            mVisibleAnimator.end();
201fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague        }
202fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague        if (mHiddenAnimator != null) {
203fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague            mHiddenAnimator.end();
204fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague        }
205fd29a841a046c6a02306adc9e4df1a5eeb466f39Spike Sprague
20682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        final float fullSize = (mIsPortrait ? (float) getWidth() : (float) getHeight());
20782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
20882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        // show
20982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        {
21082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            final ValueAnimator radiusAnimator =
21182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                ValueAnimator.ofFloat(mAnimateFrom.width()/2.0f,
21282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    fullSize-mAnimateFrom.width()/2.0f);
21382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            radiusAnimator.setDuration(RADIUS_ANIMATION_TIME);
21482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
21582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
21682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationUpdate(ValueAnimator animation) {
2174df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu                    mRadius = (Float) animation.getAnimatedValue();
21882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    mDrawCircle = true;
21982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    mFill = false;
22082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
22182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
22282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            radiusAnimator.addListener(new AnimatorListenerAdapter() {
22382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
22482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationEnd(Animator animation) {
22582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    mDrawCircle = false;
22682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    mFill = true;
22782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
22882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
22982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
23056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
23182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            alphaAnimator.setDuration(SHOW_ALPHA_ANIMATION_TIME);
23282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
23382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
23482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationUpdate(ValueAnimator animation) {
23559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    mActiveBar.setAlpha((Float) animation.getAnimatedValue());
23682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
23782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
23882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            alphaAnimator.addListener(new AnimatorListenerAdapter() {
23982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
24082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationEnd(Animator animation) {
24159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    mActiveBar.setAlpha(1.0f);
24282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
24382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
24482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
24556d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            final int deltaX = getResources()
24656d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague                .getDimensionPixelSize(R.dimen.mode_options_buttons_anim_delta_x);
24759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague            int childCount = mActiveBar.getChildCount();
24856d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            ArrayList<Animator> paddingAnimators = new ArrayList<Animator>();
24956d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            for (int i = 0; i < childCount; i++) {
25056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague                final View button;
25156d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague                if (mIsPortrait) {
25259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    button = mActiveBar.getChildAt(i);
25356d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague                } else {
25459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    button = mActiveBar.getChildAt(childCount-1-i);
25582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
25682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
25759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                final ValueAnimator paddingAnimator =
25818b22b5963e8871e539edf669d96862eec72bb5dSpike Sprague                    ValueAnimator.ofFloat(deltaX*(childCount-i), 0.0f);
25959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                paddingAnimator.setDuration(PADDING_ANIMATION_TIME);
26059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                paddingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
26159345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    @Override
26259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    public void onAnimationUpdate(ValueAnimator animation) {
26359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        if (mIsPortrait) {
26459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            button.setTranslationX((Float) animation.getAnimatedValue());
26559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        } else {
26659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                            button.setTranslationY(-((Float) animation.getAnimatedValue()));
26756d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague                        }
26859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        invalidate();
26959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    }
27059345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                });
27156d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague
27259345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                paddingAnimators.add(paddingAnimator);
27356d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            }
27459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague
27556d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            AnimatorSet paddingAnimatorSet = new AnimatorSet();
27656d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            paddingAnimatorSet.playTogether(paddingAnimators);
27782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
27882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            mVisibleAnimator = new AnimatorSet();
27982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            mVisibleAnimator.setInterpolator(Gusterpolator.INSTANCE);
28056d43cf80d40379d57ac1db697bc014d5c321b91Spike Sprague            mVisibleAnimator.playTogether(radiusAnimator, alphaAnimator, paddingAnimatorSet);
28182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        }
28282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
28382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        // hide
28482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        {
28582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            final ValueAnimator radiusAnimator =
28682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                ValueAnimator.ofFloat(fullSize-mAnimateFrom.width()/2.0f,
28782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    mAnimateFrom.width()/2.0f);
28882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            radiusAnimator.setDuration(RADIUS_ANIMATION_TIME);
28982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            radiusAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
29082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
29182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationUpdate(ValueAnimator animation) {
2924df915872c25fe61640a94c7a2c5f27eee1a1048Doris Liu                    mRadius = (Float) animation.getAnimatedValue();
29382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    mDrawCircle = true;
29482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    mFill = false;
29582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    invalidate();
29682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
29782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
29882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            radiusAnimator.addListener(new AnimatorListenerAdapter() {
29982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
30082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationEnd(Animator animation) {
30182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    if (mViewToShowHide != null) {
30282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                        mViewToShowHide.setVisibility(View.VISIBLE);
30382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                        mDrawCircle = false;
30482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                        mFill = false;
30582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                        invalidate();
30682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    }
30782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
30882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
30982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
31082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            final ValueAnimator alphaAnimator = ValueAnimator.ofFloat(1.0f, 0.0f);
31182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            alphaAnimator.setDuration(HIDE_ALPHA_ANIMATION_TIME);
31282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
31382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
31482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationUpdate(ValueAnimator animation) {
31559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    mActiveBar.setAlpha((Float) animation.getAnimatedValue());
31682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    invalidate();
31782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
31882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
31982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            alphaAnimator.addListener(new AnimatorListenerAdapter() {
32082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                @Override
32182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                public void onAnimationEnd(Animator animation) {
3222a58938576e6d4220c02cf0b9a8226a1d3bcf176Spike Sprague                    setVisibility(View.INVISIBLE);
32359345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    if (mActiveBar != mMainBar) {
32459345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        mActiveBar.setAlpha(1.0f);
32559345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                        mActiveBar.setVisibility(View.INVISIBLE);
32659345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    }
32759345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    mMainBar.setAlpha(1.0f);
32859345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    mMainBar.setVisibility(View.VISIBLE);
32959345144c4bde59b81bb19c95cdd977c1d1a9cd4Spike Sprague                    mActiveBar = mMainBar;
33082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                    invalidate();
33182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague                }
33282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            });
33382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
33482fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            mHiddenAnimator = new AnimatorSet();
33582fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            mHiddenAnimator.setInterpolator(Gusterpolator.INSTANCE);
33682fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague            mHiddenAnimator.playTogether(radiusAnimator, alphaAnimator);
33782fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        }
33882fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
33982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
34082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    public void animateVisible() {
341591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague        if (mIsHiddenOrHiding) {
342591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            if (mViewToShowHide != null) {
343591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague                mViewToShowHide.setVisibility(View.INVISIBLE);
344591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            }
345591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            mHiddenAnimator.cancel();
346591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            mVisibleAnimator.end();
3472a58938576e6d4220c02cf0b9a8226a1d3bcf176Spike Sprague            setVisibility(View.VISIBLE);
348591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            mVisibleAnimator.start();
34982fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague        }
350591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague        mIsHiddenOrHiding = false;
35182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
35282fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague
35382fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    public void animateHidden() {
354591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague        if (!mIsHiddenOrHiding) {
355591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            mVisibleAnimator.cancel();
356591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            mHiddenAnimator.end();
357591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague            mHiddenAnimator.start();
358591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague        }
359591eec6465d29bbc053e164071c4c3a7c260a1d3Spike Sprague        mIsHiddenOrHiding = true;
36082fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague    }
36182fa6ae85f7c07fef480eb1cd0cf7f578b150676Spike Sprague}