// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.widget.newtab; import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.Button; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.widget.animation.AnimatorProperties; import java.util.ArrayList; import java.util.List; /** * Button for creating new tabs. */ public class NewTabButton extends Button implements Drawable.Callback { private final Drawable mNormalDrawable; private final Drawable mIncognitoDrawable; private boolean mIsIncognito; private AnimatorSet mTransitionAnimation; /** * Constructor for inflating from XML. */ public NewTabButton(Context context, AttributeSet attrs) { super(context, attrs); mNormalDrawable = ApiCompatibilityUtils.getDrawable( getResources(), R.drawable.btn_new_tab_white); mNormalDrawable.setBounds( 0, 0, mNormalDrawable.getIntrinsicWidth(), mNormalDrawable.getIntrinsicHeight()); mNormalDrawable.setCallback(this); mIncognitoDrawable = ApiCompatibilityUtils.getDrawable( getResources(), R.drawable.btn_new_tab_incognito); mIncognitoDrawable.setBounds( 0, 0, mIncognitoDrawable.getIntrinsicWidth(), mIncognitoDrawable.getIntrinsicHeight()); mIncognitoDrawable.setCallback(this); mIsIncognito = false; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int desiredWidth = Math.max( mIncognitoDrawable.getIntrinsicWidth(), mNormalDrawable.getIntrinsicWidth()); desiredWidth += getPaddingLeft() + getPaddingRight(); widthMeasureSpec = MeasureSpec.makeMeasureSpec(desiredWidth, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this); int paddingStart = ApiCompatibilityUtils.getPaddingStart(this); int widthWithoutPadding = getWidth() - paddingStart; canvas.save(); if (!isRtl) canvas.translate(paddingStart, 0); canvas.save(); canvas.translate(0, (getHeight() - mNormalDrawable.getIntrinsicHeight()) / 2.f); if (isRtl) { canvas.translate(widthWithoutPadding - mNormalDrawable.getIntrinsicWidth(), 0); } mNormalDrawable.draw(canvas); canvas.restore(); if (mIsIncognito || (mTransitionAnimation != null && mTransitionAnimation.isRunning())) { canvas.save(); canvas.translate(0, (getHeight() - mIncognitoDrawable.getIntrinsicHeight()) / 2.f); if (isRtl) { canvas.translate(widthWithoutPadding - mIncognitoDrawable.getIntrinsicWidth(), 0); } mIncognitoDrawable.draw(canvas); canvas.restore(); } canvas.restore(); } @Override public void invalidateDrawable(Drawable dr) { if (dr == mIncognitoDrawable || dr == mNormalDrawable) { invalidate(); } else { super.invalidateDrawable(dr); } } /** * Updates the visual state based on whether incognito or normal tabs are being created. * @param incognito Whether the button is now used for creating incognito tabs. */ public void setIsIncognito(boolean incognito) { if (mIsIncognito == incognito) return; mIsIncognito = incognito; if (mTransitionAnimation != null) { mTransitionAnimation.cancel(); mTransitionAnimation = null; } Drawable fadeOutDrawable = incognito ? mNormalDrawable : mIncognitoDrawable; Drawable fadeInDrawable = incognito ? mIncognitoDrawable : mNormalDrawable; if (getVisibility() != VISIBLE) { fadeOutDrawable.setAlpha(0); fadeInDrawable.setAlpha(255); return; } List<Animator> animations = new ArrayList<Animator>(); Animator animation = ObjectAnimator.ofInt( fadeOutDrawable, AnimatorProperties.DRAWABLE_ALPHA_PROPERTY, 255, 0); animation.setDuration(100); animations.add(animation); animation = ObjectAnimator.ofInt( fadeInDrawable, AnimatorProperties.DRAWABLE_ALPHA_PROPERTY, 0, 255); animation.setStartDelay(150); animation.setDuration(100); animations.add(animation); mTransitionAnimation = new AnimatorSet(); mTransitionAnimation.playTogether(animations); mTransitionAnimation.start(); } @Override protected void drawableStateChanged() { super.drawableStateChanged(); mNormalDrawable.setState(getDrawableState()); mIncognitoDrawable.setState(getDrawableState()); } }