| Index: chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
|
| diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
|
| deleted file mode 100644
|
| index 39b829925c41e0ed695718b050f7dcfc92cafccd..0000000000000000000000000000000000000000
|
| --- a/chrome/android/java_staging/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
|
| +++ /dev/null
|
| @@ -1,1903 +0,0 @@
|
| -// 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.toolbar;
|
| -
|
| -import android.animation.Animator;
|
| -import android.animation.AnimatorListenerAdapter;
|
| -import android.animation.AnimatorSet;
|
| -import android.animation.ObjectAnimator;
|
| -import android.animation.ValueAnimator;
|
| -import android.animation.ValueAnimator.AnimatorUpdateListener;
|
| -import android.annotation.SuppressLint;
|
| -import android.content.Context;
|
| -import android.content.res.ColorStateList;
|
| -import android.content.res.Resources;
|
| -import android.graphics.Canvas;
|
| -import android.graphics.Color;
|
| -import android.graphics.Point;
|
| -import android.graphics.PorterDuff;
|
| -import android.graphics.Rect;
|
| -import android.graphics.drawable.BitmapDrawable;
|
| -import android.graphics.drawable.ColorDrawable;
|
| -import android.graphics.drawable.Drawable;
|
| -import android.graphics.drawable.TransitionDrawable;
|
| -import android.os.Build;
|
| -import android.os.SystemClock;
|
| -import android.util.AttributeSet;
|
| -import android.util.Property;
|
| -import android.view.Gravity;
|
| -import android.view.MotionEvent;
|
| -import android.view.View;
|
| -import android.view.View.OnClickListener;
|
| -import android.view.View.OnLongClickListener;
|
| -import android.view.ViewGroup;
|
| -import android.view.WindowManager;
|
| -import android.view.animation.LinearInterpolator;
|
| -import android.widget.FrameLayout;
|
| -import android.widget.ImageView;
|
| -import android.widget.TextView;
|
| -import android.widget.Toast;
|
| -
|
| -import org.chromium.base.ApiCompatibilityUtils;
|
| -import org.chromium.base.SysUtils;
|
| -import org.chromium.base.VisibleForTesting;
|
| -import org.chromium.base.metrics.RecordUserAction;
|
| -import org.chromium.chrome.R;
|
| -import org.chromium.chrome.browser.Tab;
|
| -import org.chromium.chrome.browser.compositor.Invalidator;
|
| -import org.chromium.chrome.browser.document.BrandColorUtils;
|
| -import org.chromium.chrome.browser.ntp.NewTabPage;
|
| -import org.chromium.chrome.browser.omnibox.LocationBar;
|
| -import org.chromium.chrome.browser.omnibox.LocationBarPhone;
|
| -import org.chromium.chrome.browser.omnibox.UrlContainer;
|
| -import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
|
| -import org.chromium.chrome.browser.util.FeatureUtilities;
|
| -import org.chromium.chrome.browser.util.MathUtils;
|
| -import org.chromium.chrome.browser.widget.TintedImageButton;
|
| -import org.chromium.chrome.browser.widget.newtab.NewTabButton;
|
| -import org.chromium.ui.base.LocalizationUtils;
|
| -import org.chromium.ui.interpolators.BakedBezierInterpolator;
|
| -
|
| -import java.util.ArrayList;
|
| -import java.util.HashSet;
|
| -import java.util.List;
|
| -import java.util.Set;
|
| -
|
| -/**
|
| - * Phone specific toolbar implementation.
|
| - */
|
| -public class ToolbarPhone extends ToolbarLayout
|
| - implements Invalidator.Client, OnClickListener, OnLongClickListener,
|
| - NewTabPage.OnSearchBoxScrollListener {
|
| -
|
| - public static final int URL_FOCUS_CHANGE_ANIMATION_DURATION_MS = 250;
|
| - private static final int URL_FOCUS_TOOLBAR_BUTTONS_TRANSLATION_X_DP = 10;
|
| - private static final int URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS = 100;
|
| - private static final int URL_CLEAR_FOCUS_TABSTACK_DELAY_MS = 200;
|
| - private static final int URL_CLEAR_FOCUS_MENU_DELAY_MS = 250;
|
| -
|
| - private static final int TAB_SWITCHER_MODE_ENTER_ANIMATION_DURATION_MS = 200;
|
| - private static final int TAB_SWITCHER_MODE_EXIT_NORMAL_ANIMATION_DURATION_MS = 200;
|
| - private static final int TAB_SWITCHER_MODE_EXIT_FADE_ANIMATION_DURATION_MS = 100;
|
| - private static final int TAB_SWITCHER_MODE_POST_EXIT_ANIMATION_DURATION_MS = 100;
|
| -
|
| - private static final float UNINITIALIZED_PERCENT = -1f;
|
| -
|
| - private static final int BRAND_COLOR_TRANSITION_DURATION_MS = 250;
|
| -
|
| - static final int LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA = 51;
|
| -
|
| - private LocationBarPhone mPhoneLocationBar;
|
| -
|
| - private ViewGroup mToolbarButtonsContainer;
|
| - private ImageView mToggleTabStackButton;
|
| - private NewTabButton mNewTabButton;
|
| - private TintedImageButton mHomeButton;
|
| - private TextView mUrlBar;
|
| - private UrlContainer mUrlContainer;
|
| - private View mUrlActionsContainer;
|
| - private ImageView mToolbarShadow;
|
| -
|
| - private ObjectAnimator mTabSwitcherModeAnimation;
|
| - private ObjectAnimator mDelayedTabSwitcherModeAnimation;
|
| -
|
| - private final List<View> mTabSwitcherModeViews = new ArrayList<View>();
|
| - private final Set<View> mBrowsingModeViews = new HashSet<View>();
|
| - private boolean mInTabSwitcherMode;
|
| - // This determines whether or not the toolbar draws as expected (false) or whether it always
|
| - // draws as if it's showing the non-tabswitcher, non-animating toolbar. This is used in grabbing
|
| - // a bitmap to use as a texture representation of this view.
|
| - private boolean mTextureCaptureMode;
|
| - private boolean mAnimateNormalToolbar;
|
| - private boolean mDelayingTabSwitcherAnimation;
|
| -
|
| - private ColorDrawable mTabSwitcherAnimationBgOverlay;
|
| - private TabSwitcherDrawable mTabSwitcherAnimationTabStackDrawable;
|
| - private Drawable mTabSwitcherAnimationMenuDrawable;
|
| - // Value that determines the amount of transition from the normal toolbar mode to TabSwitcher
|
| - // mode. 0 = entirely in normal mode and 1.0 = entirely in TabSwitcher mode. In between values
|
| - // can be used for animating between the two view modes.
|
| - private float mTabSwitcherModePercent = 0;
|
| - private boolean mUIAnimatingTabSwitcherTransition;
|
| -
|
| - // Used to clip the toolbar during the fade transition into and out of TabSwitcher mode. Only
|
| - // used when |mAnimateNormalToolbar| is false.
|
| - private Rect mClipRect;
|
| -
|
| - private OnClickListener mTabSwitcherListener;
|
| - private OnClickListener mNewTabListener;
|
| -
|
| - private boolean mUrlFocusChangeInProgress;
|
| - /** 1.0 is 100% focused, 0 is completely unfocused */
|
| - private float mUrlFocusChangePercent;
|
| - /** 1.0 is 100% expanded to full width, 0 is original collapsed size. */
|
| - private float mUrlExpansionPercent;
|
| - private AnimatorSet mUrlFocusLayoutAnimator;
|
| - private boolean mDisableLocationBarRelayout;
|
| - private boolean mLayoutLocationBarInFocusedMode;
|
| - private int mUnfocusedLocationBarLayoutWidth;
|
| - private int mUnfocusedLocationBarLayoutLeft;
|
| - private boolean mUnfocusedLocationBarUsesTransparentBg;
|
| -
|
| - private int mUrlBackgroundAlpha = 255;
|
| - private float mNtpSearchBoxScrollPercent = UNINITIALIZED_PERCENT;
|
| - private ColorDrawable mToolbarBackground;
|
| - private Drawable mLocationBarBackground;
|
| - private boolean mForceDrawLocationBarBackground;
|
| - private TabSwitcherDrawable mTabSwitcherButtonDrawable;
|
| - private TabSwitcherDrawable mTabSwitcherButtonDrawableLight;
|
| -
|
| - private final Rect mUrlViewportBounds = new Rect();
|
| - private final Rect mUrlBackgroundPadding = new Rect();
|
| - private final Rect mBackgroundOverlayBounds = new Rect();
|
| - private final Rect mLocationBarBackgroundOffset = new Rect();
|
| -
|
| - private final Rect mNtpSearchBoxOriginalBounds = new Rect();
|
| - private final Rect mNtpSearchBoxTransformedBounds = new Rect();
|
| -
|
| - private final int mLocationBarInsets;
|
| - private final int mToolbarSidePadding;
|
| -
|
| - private ValueAnimator mBrandColorTransitionAnimation;
|
| - private boolean mBrandColorTransitionActive;
|
| -
|
| - /**
|
| - * Used to specify the visual state of the toolbar.
|
| - */
|
| - private enum VisualState {
|
| - TAB_SWITCHER_INCOGNITO,
|
| - TAB_SWITCHER_NORMAL,
|
| - NORMAL,
|
| - INCOGNITO,
|
| - BRAND_COLOR,
|
| - NEW_TAB_NORMAL
|
| - }
|
| -
|
| - private VisualState mVisualState = VisualState.NORMAL;
|
| - private VisualState mOverlayDrawablesVisualState;
|
| - private boolean mUseLightToolbarDrawables;
|
| -
|
| - private NewTabPage mVisibleNewTabPage;
|
| - private float mPreTextureCaptureAlpha = 1f;
|
| - private boolean mIsOverlayTabStackDrawableLight;
|
| -
|
| - // The following are some properties used during animation. We use explicit property classes
|
| - // to avoid the cost of reflection for each animation setup.
|
| -
|
| - private final Property<ToolbarPhone, Float> mUrlFocusChangePercentProperty =
|
| - new Property<ToolbarPhone, Float>(Float.class, "") {
|
| - @Override
|
| - public Float get(ToolbarPhone object) {
|
| - return object.mUrlFocusChangePercent;
|
| - }
|
| -
|
| - @Override
|
| - public void set(ToolbarPhone object, Float value) {
|
| - setUrlFocusChangePercent(value);
|
| - }
|
| - };
|
| -
|
| - private final Property<ToolbarPhone, Float> mTabSwitcherModePercentProperty =
|
| - new Property<ToolbarPhone, Float>(Float.class, "") {
|
| - @Override
|
| - public Float get(ToolbarPhone object) {
|
| - return object.mTabSwitcherModePercent;
|
| - }
|
| -
|
| - @Override
|
| - public void set(ToolbarPhone object, Float value) {
|
| - object.mTabSwitcherModePercent = value;
|
| - triggerPaintInvalidate(ToolbarPhone.this);
|
| - }
|
| - };
|
| -
|
| - /**
|
| - * Constructs a ToolbarPhone object.
|
| - * @param context The Context in which this View object is created.
|
| - * @param attrs The AttributeSet that was specified with this View.
|
| - */
|
| - public ToolbarPhone(Context context, AttributeSet attrs) {
|
| - super(context, attrs);
|
| - mToolbarSidePadding = getResources().getDimensionPixelOffset(
|
| - R.dimen.toolbar_edge_padding);
|
| - // Insets used for the PhoneLocatioBar background drawable.
|
| - mLocationBarInsets = getResources().getDimensionPixelSize(R.dimen.location_bar_margin_top)
|
| - + getResources().getDimensionPixelSize(R.dimen.location_bar_margin_bottom);
|
| - }
|
| -
|
| - @Override
|
| - public void onFinishInflate() {
|
| - super.onFinishInflate();
|
| - mPhoneLocationBar = (LocationBarPhone) findViewById(R.id.location_bar);
|
| -
|
| - mToolbarButtonsContainer = (ViewGroup) findViewById(R.id.toolbar_buttons);
|
| -
|
| - mHomeButton = (TintedImageButton) findViewById(R.id.home_button);
|
| -
|
| - mUrlBar = (TextView) findViewById(R.id.url_bar);
|
| - mUrlContainer = (UrlContainer) findViewById(R.id.url_container);
|
| -
|
| - mUrlActionsContainer = findViewById(R.id.url_action_container);
|
| -
|
| - mBrowsingModeViews.add(mPhoneLocationBar);
|
| -
|
| - mToolbarBackground = new ColorDrawable(getToolbarColorForVisualState(VisualState.NORMAL));
|
| - mTabSwitcherAnimationBgOverlay =
|
| - new ColorDrawable(getToolbarColorForVisualState(VisualState.NORMAL));
|
| -
|
| - mLocationBarBackground =
|
| - ApiCompatibilityUtils.getDrawable(getResources(), R.drawable.inset_textbox);
|
| - mLocationBarBackground.getPadding(mUrlBackgroundPadding);
|
| - mPhoneLocationBar.setPadding(
|
| - mUrlBackgroundPadding.left, mUrlBackgroundPadding.top,
|
| - mUrlBackgroundPadding.right, mUrlBackgroundPadding.bottom);
|
| -
|
| - setLayoutTransition(null);
|
| -
|
| - mMenuButton.setVisibility(shouldShowMenuButton() ? View.VISIBLE : View.GONE);
|
| - if (FeatureUtilities.isDocumentMode(getContext())) {
|
| - ApiCompatibilityUtils.setMarginEnd(
|
| - (MarginLayoutParams) mMenuButton.getLayoutParams(),
|
| - getResources().getDimensionPixelSize(R.dimen.document_toolbar_menu_offset));
|
| - }
|
| -
|
| - finishInflateForTabSwitchingResources();
|
| -
|
| - setWillNotDraw(false);
|
| - }
|
| -
|
| - private boolean isTabSwitchingEnabled() {
|
| - return !FeatureUtilities.isDocumentMode(getContext());
|
| - }
|
| -
|
| - private void finishInflateForTabSwitchingResources() {
|
| - mToggleTabStackButton = (ImageView) findViewById(R.id.tab_switcher_button);
|
| - mNewTabButton = (NewTabButton) findViewById(R.id.new_tab_button);
|
| -
|
| - if (!isTabSwitchingEnabled()) {
|
| - assert mToolbarButtonsContainer.indexOfChild(mToggleTabStackButton) >= 0;
|
| - mToolbarButtonsContainer.removeView(mToggleTabStackButton);
|
| - mToggleTabStackButton = null;
|
| - assert indexOfChild(mNewTabButton) >= 0;
|
| - removeView(mNewTabButton);
|
| - mNewTabButton = null;
|
| - } else {
|
| - mToggleTabStackButton.setClickable(false);
|
| - Resources resources = getResources();
|
| - mTabSwitcherButtonDrawable =
|
| - TabSwitcherDrawable.createTabSwitcherDrawable(resources, false);
|
| - mTabSwitcherButtonDrawableLight =
|
| - TabSwitcherDrawable.createTabSwitcherDrawable(resources, true);
|
| - mToggleTabStackButton.setImageDrawable(mTabSwitcherButtonDrawable);
|
| - mTabSwitcherModeViews.add(mNewTabButton);
|
| -
|
| - // Ensure that the new tab button will not draw over the toolbar buttons if the
|
| - // translated string is long. Set a margin to the size of the toolbar button container
|
| - // for the new tab button.
|
| - WindowManager wm = (WindowManager) getContext().getSystemService(
|
| - Context.WINDOW_SERVICE);
|
| - Point screenSize = new Point();
|
| - wm.getDefaultDisplay().getSize(screenSize);
|
| -
|
| - mToolbarButtonsContainer.measure(
|
| - MeasureSpec.makeMeasureSpec(screenSize.x, MeasureSpec.AT_MOST),
|
| - MeasureSpec.makeMeasureSpec(screenSize.y, MeasureSpec.AT_MOST));
|
| -
|
| - ApiCompatibilityUtils.setMarginEnd(getFrameLayoutParams(mNewTabButton),
|
| - mToolbarButtonsContainer.getMeasuredWidth());
|
| - }
|
| - }
|
| -
|
| - /**
|
| - * Sets up click and key listeners once we have native library available to handle clicks.
|
| - */
|
| - @Override
|
| - public void onNativeLibraryReady() {
|
| - super.onNativeLibraryReady();
|
| - getLocationBar().onNativeLibraryReady();
|
| -
|
| - if (isTabSwitchingEnabled()) {
|
| - mToggleTabStackButton.setOnClickListener(this);
|
| - mToggleTabStackButton.setOnLongClickListener(this);
|
| - mToggleTabStackButton.setOnKeyListener(new KeyboardNavigationListener() {
|
| - @Override
|
| - public View getNextFocusForward() {
|
| - if (mMenuButton != null && mMenuButton.isShown()) {
|
| - return mMenuButton;
|
| - } else {
|
| - return getCurrentTabView();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public View getNextFocusBackward() {
|
| - return findViewById(R.id.url_bar);
|
| - }
|
| - });
|
| - mNewTabButton.setOnClickListener(this);
|
| - }
|
| - mHomeButton.setOnClickListener(this);
|
| -
|
| - mMenuButton.setOnKeyListener(new KeyboardNavigationListener() {
|
| - @Override
|
| - public View getNextFocusForward() {
|
| - return getCurrentTabView();
|
| - }
|
| -
|
| - @Override
|
| - public View getNextFocusBackward() {
|
| - return mToggleTabStackButton;
|
| - }
|
| -
|
| - @Override
|
| - protected boolean handleEnterKeyPress() {
|
| - return getMenuButtonHelper().onEnterKeyPress(mMenuButton);
|
| - }
|
| - });
|
| - onHomeButtonUpdate(HomepageManager.isHomepageEnabled(getContext()));
|
| -
|
| - updateVisualsForToolbarState(mInTabSwitcherMode);
|
| - }
|
| -
|
| - @Override
|
| - public boolean onInterceptTouchEvent(MotionEvent ev) {
|
| - // If the NTP is partially scrolled, prevent all touch events to the child views. This
|
| - // is to not allow a secondary touch event to trigger entering the tab switcher, which
|
| - // can lead to really odd snapshots and transitions to the switcher.
|
| - if (mNtpSearchBoxScrollPercent != 0f
|
| - && mNtpSearchBoxScrollPercent != 1f
|
| - && mNtpSearchBoxScrollPercent != UNINITIALIZED_PERCENT) {
|
| - return true;
|
| - }
|
| - return super.onInterceptTouchEvent(ev);
|
| - }
|
| -
|
| - @Override
|
| - public void onClick(View v) {
|
| - if (mToggleTabStackButton == v) {
|
| - // The button is clickable before the native library is loaded
|
| - // and the listener is setup.
|
| - if (mToggleTabStackButton != null && mToggleTabStackButton.isClickable()
|
| - && mTabSwitcherListener != null) {
|
| - mTabSwitcherListener.onClick(mToggleTabStackButton);
|
| - RecordUserAction.record("MobileToolbarShowStackView");
|
| - }
|
| - } else if (mNewTabButton == v) {
|
| - v.setEnabled(false);
|
| -
|
| - if (mNewTabListener != null) {
|
| - mNewTabListener.onClick(v);
|
| - RecordUserAction.record("MobileToolbarStackViewNewTab");
|
| - RecordUserAction.record("MobileNewTabOpened");
|
| - // TODO(kkimlabs): Record UMA action for homepage button.
|
| - }
|
| - } else if (mHomeButton == v) {
|
| - openHomepage();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public boolean onLongClick(View v) {
|
| - int stringResourceId = -1;
|
| - if (v == mToggleTabStackButton) {
|
| - stringResourceId = R.string.open_tabs;
|
| - }
|
| - if (stringResourceId != -1) {
|
| - Context ctx = getContext();
|
| - // Display the tooltip for the view being long clicked.
|
| - final int screenWidth = getResources().getDisplayMetrics().widthPixels;
|
| - final int[] screenPos = new int[2];
|
| - v.getLocationOnScreen(screenPos);
|
| - final int width = v.getWidth();
|
| -
|
| - Toast toast = Toast.makeText(
|
| - ctx, getResources().getString(stringResourceId), Toast.LENGTH_SHORT);
|
| - toast.setGravity(
|
| - Gravity.TOP | Gravity.END,
|
| - screenWidth - screenPos[0] - width / 2,
|
| - getHeight());
|
| - toast.show();
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - @Override
|
| - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
| - if (!mDisableLocationBarRelayout) {
|
| - super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
| -
|
| - boolean changed = layoutLocationBar(MeasureSpec.getSize(widthMeasureSpec));
|
| - if (!mInTabSwitcherMode) setUrlFocusChangePercent(mUrlFocusChangePercent);
|
| - if (!changed) return;
|
| - } else {
|
| - updateUnfocusedLocationBarLayoutParams();
|
| - }
|
| -
|
| - super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
| - }
|
| -
|
| - private void updateUnfocusedLocationBarLayoutParams() {
|
| - boolean hasVisibleViewPriorToUrlBar = false;
|
| - for (int i = 0; i < mPhoneLocationBar.getChildCount(); i++) {
|
| - View child = mPhoneLocationBar.getChildAt(i);
|
| - if (child == mUrlContainer) break;
|
| - if (child.getVisibility() != GONE) {
|
| - hasVisibleViewPriorToUrlBar = true;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - int leftViewBounds = getViewBoundsLeftOfLocationBar();
|
| - if (!hasVisibleViewPriorToUrlBar) leftViewBounds += mToolbarSidePadding;
|
| - int rightViewBounds = getViewBoundsRightOfLocationBar();
|
| -
|
| - if (!mPhoneLocationBar.hasVisibleViewsAfterUrlBarWhenUnfocused()) {
|
| - // Add spacing between the end of the URL and the edge of the omnibox drawable.
|
| - // This only applies if there is no end aligned view that should be visible
|
| - // while the omnibox is unfocused.
|
| - if (ApiCompatibilityUtils.isLayoutRtl(mPhoneLocationBar)) {
|
| - leftViewBounds += mToolbarSidePadding;
|
| - } else {
|
| - rightViewBounds -= mToolbarSidePadding;
|
| - }
|
| - }
|
| -
|
| - mUnfocusedLocationBarLayoutWidth = rightViewBounds - leftViewBounds;
|
| - mUnfocusedLocationBarLayoutLeft = leftViewBounds;
|
| - }
|
| -
|
| - /**
|
| - * @return The background drawable for the fullscreen overlay.
|
| - */
|
| - @VisibleForTesting
|
| - ColorDrawable getOverlayDrawable() {
|
| - return mTabSwitcherAnimationBgOverlay;
|
| - }
|
| -
|
| - /**
|
| - * @return The background drawable for the toolbar view.
|
| - */
|
| - @VisibleForTesting
|
| - ColorDrawable getBackgroundDrawable() {
|
| - return mToolbarBackground;
|
| - }
|
| -
|
| - @SuppressLint("RtlHardcoded")
|
| - private boolean layoutLocationBar(int containerWidth) {
|
| - // Note that Toolbar's direction depends on system layout direction while
|
| - // LocationBar's direction depends on its text inside.
|
| - FrameLayout.LayoutParams locationBarLayoutParams =
|
| - getFrameLayoutParams(getLocationBar().getContainerView());
|
| -
|
| - // Chrome prevents layout_gravity="left" from being defined in XML, but it simplifies
|
| - // the logic, so it is manually specified here.
|
| - locationBarLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;
|
| -
|
| - int width = 0;
|
| - int leftMargin = 0;
|
| -
|
| - // Always update the unfocused layout params regardless of whether we are using
|
| - // those in this current layout pass as they are needed for animations.
|
| - updateUnfocusedLocationBarLayoutParams();
|
| -
|
| - if (mLayoutLocationBarInFocusedMode || mVisualState == VisualState.NEW_TAB_NORMAL) {
|
| - int priorVisibleWidth = 0;
|
| - for (int i = 0; i < mPhoneLocationBar.getChildCount(); i++) {
|
| - View child = mPhoneLocationBar.getChildAt(i);
|
| - if (child == mPhoneLocationBar.getFirstViewVisibleWhenFocused()) break;
|
| - if (child.getVisibility() == GONE) continue;
|
| - priorVisibleWidth += child.getMeasuredWidth();
|
| - }
|
| -
|
| - width = containerWidth - (2 * mToolbarSidePadding) + priorVisibleWidth;
|
| - if (ApiCompatibilityUtils.isLayoutRtl(mPhoneLocationBar)) {
|
| - leftMargin = mToolbarSidePadding;
|
| - } else {
|
| - leftMargin = -priorVisibleWidth + mToolbarSidePadding;
|
| - }
|
| - } else {
|
| - width = mUnfocusedLocationBarLayoutWidth;
|
| - leftMargin = mUnfocusedLocationBarLayoutLeft;
|
| - }
|
| -
|
| - boolean changed = false;
|
| - changed |= (width != locationBarLayoutParams.width);
|
| - locationBarLayoutParams.width = width;
|
| -
|
| - changed |= (leftMargin != locationBarLayoutParams.leftMargin);
|
| - locationBarLayoutParams.leftMargin = leftMargin;
|
| -
|
| - return changed;
|
| - }
|
| -
|
| - private int getViewBoundsLeftOfLocationBar() {
|
| - // Uses getMeasuredWidth()s instead of getLeft() because this is called in onMeasure
|
| - // and the layout values have not yet been set.
|
| - if (mVisualState == VisualState.NEW_TAB_NORMAL) {
|
| - return 0;
|
| - } else if (ApiCompatibilityUtils.isLayoutRtl(this)) {
|
| - return Math.max(
|
| - mToolbarSidePadding, mToolbarButtonsContainer.getMeasuredWidth());
|
| - } else {
|
| - return mHomeButton.getVisibility() != GONE
|
| - ? mHomeButton.getMeasuredWidth() : mToolbarSidePadding;
|
| - }
|
| - }
|
| -
|
| - private int getViewBoundsRightOfLocationBar() {
|
| - // Uses getMeasuredWidth()s instead of getRight() because this is called in onMeasure
|
| - // and the layout values have not yet been set.
|
| - if (mVisualState == VisualState.NEW_TAB_NORMAL) {
|
| - return getMeasuredWidth();
|
| - } else if (ApiCompatibilityUtils.isLayoutRtl(this)) {
|
| - return getMeasuredWidth() - (mHomeButton.getVisibility() != GONE
|
| - ? mHomeButton.getMeasuredWidth() : mToolbarSidePadding);
|
| - } else {
|
| - int margin = Math.max(
|
| - mToolbarSidePadding, mToolbarButtonsContainer.getMeasuredWidth());
|
| - return getMeasuredWidth() - margin;
|
| - }
|
| - }
|
| -
|
| - private void updateToolbarBackground(int color) {
|
| - mToolbarBackground.setColor(color);
|
| - invalidate();
|
| - }
|
| -
|
| - private void updateToolbarBackground(VisualState visualState) {
|
| - updateToolbarBackground(getToolbarColorForVisualState(visualState));
|
| - }
|
| -
|
| - private int getToolbarColorForVisualState(final VisualState visualState) {
|
| - Resources res = getResources();
|
| - switch (visualState) {
|
| - case NEW_TAB_NORMAL:
|
| - return Color.TRANSPARENT;
|
| - case NORMAL :
|
| - return res.getColor(R.color.default_primary_color);
|
| - case INCOGNITO:
|
| - return res.getColor(R.color.incognito_primary_color);
|
| - case BRAND_COLOR:
|
| - return getToolbarDataProvider().getPrimaryColor();
|
| - case TAB_SWITCHER_NORMAL:
|
| - case TAB_SWITCHER_INCOGNITO:
|
| - return res.getColor(R.color.tab_switcher_background);
|
| - default:
|
| - assert false;
|
| - return res.getColor(R.color.default_primary_color);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - protected void dispatchDraw(Canvas canvas) {
|
| - if (!mTextureCaptureMode && mToolbarBackground.getColor() != Color.TRANSPARENT) {
|
| - // Update to compensate for orientation changes.
|
| - mToolbarBackground.setBounds(0, 0, getWidth(), getHeight());
|
| - mToolbarBackground.draw(canvas);
|
| - }
|
| -
|
| - if (mLocationBarBackground != null
|
| - && (mPhoneLocationBar.getVisibility() == VISIBLE || mTextureCaptureMode)) {
|
| - // Calculate the visible boundaries of the left and right most child views
|
| - // of the location bar.
|
| - int leftViewPosition = getViewBoundsLeftOfLocationBar();
|
| - int rightViewPosition = getViewBoundsRightOfLocationBar();
|
| -
|
| - leftViewPosition -= mUrlBackgroundPadding.left;
|
| - if (mUrlExpansionPercent != 0f) {
|
| - leftViewPosition *= (1f - mUrlExpansionPercent);
|
| - leftViewPosition -= mUrlBackgroundPadding.left * mUrlExpansionPercent;
|
| - }
|
| -
|
| - rightViewPosition += mUrlBackgroundPadding.right;
|
| - if (mUrlExpansionPercent != 0f) {
|
| - rightViewPosition += ((getWidth() - rightViewPosition) * mUrlExpansionPercent);
|
| - rightViewPosition += mUrlBackgroundPadding.right * mUrlExpansionPercent;
|
| - }
|
| -
|
| - // The bounds are set by the following:
|
| - // - The left most visible location bar child view.
|
| - // - The top of the viewport is aligned with the top of the location bar.
|
| - // - The right most visible location bar child view.
|
| - // - The bottom of the viewport is aligned with the bottom of the location bar.
|
| - // Additional padding can be applied for use during animations.
|
| - mUrlViewportBounds.set(
|
| - leftViewPosition,
|
| - 0,
|
| - rightViewPosition,
|
| - (int) (mPhoneLocationBar.getMeasuredHeight()
|
| - + (getHeight() - mPhoneLocationBar.getMeasuredHeight()
|
| - + mUrlBackgroundPadding.bottom + mUrlBackgroundPadding.top)
|
| - * mUrlExpansionPercent));
|
| - mUrlViewportBounds.offset(0, (int) (mPhoneLocationBar.getY()
|
| - - (mUrlBackgroundPadding.top * mUrlExpansionPercent)));
|
| - }
|
| -
|
| - if (mTextureCaptureMode) {
|
| - drawTabSwitcherAnimationOverlay(canvas, 0.f);
|
| - } else {
|
| - boolean tabSwitcherAnimationFinished = false;
|
| - if (mTabSwitcherModeAnimation != null) {
|
| - tabSwitcherAnimationFinished = !mTabSwitcherModeAnimation.isRunning();
|
| -
|
| - // Perform the fade logic before super.dispatchDraw(canvas) so that we can properly
|
| - // set the values before the draw happens.
|
| - if (!mAnimateNormalToolbar) {
|
| - drawTabSwitcherFadeAnimation(
|
| - tabSwitcherAnimationFinished, mTabSwitcherModePercent);
|
| - }
|
| - }
|
| -
|
| - super.dispatchDraw(canvas);
|
| -
|
| - if (mTabSwitcherModeAnimation != null) {
|
| - // Perform the overlay logic after super.dispatchDraw(canvas) as we need to draw on
|
| - // top of the current views.
|
| - if (mAnimateNormalToolbar) {
|
| - drawTabSwitcherAnimationOverlay(canvas, mTabSwitcherModePercent);
|
| - }
|
| -
|
| - // Clear the animation.
|
| - if (tabSwitcherAnimationFinished) mTabSwitcherModeAnimation = null;
|
| - }
|
| - }
|
| - }
|
| -
|
| - // NewTabPage.OnSearchBoxScrollListener
|
| - @Override
|
| - public void onScrollChanged(float scrollPercentage) {
|
| - if (scrollPercentage == mNtpSearchBoxScrollPercent) return;
|
| -
|
| - mNtpSearchBoxScrollPercent = scrollPercentage;
|
| - updateUrlExpansionPercent();
|
| - updateUrlExpansionAnimation();
|
| - }
|
| -
|
| - /**
|
| - * Updates percentage of current the URL focus change animation.
|
| - * @param percent 1.0 is 100% focused, 0 is completely unfocused.
|
| - */
|
| - private void setUrlFocusChangePercent(float percent) {
|
| - mUrlFocusChangePercent = percent;
|
| - updateUrlExpansionPercent();
|
| - updateUrlExpansionAnimation();
|
| - }
|
| -
|
| - private void updateUrlExpansionPercent() {
|
| - mUrlExpansionPercent = Math.max(mNtpSearchBoxScrollPercent, mUrlFocusChangePercent);
|
| - assert mUrlExpansionPercent >= 0;
|
| - assert mUrlExpansionPercent <= 1;
|
| - }
|
| -
|
| - private void updateUrlExpansionAnimation() {
|
| - if (mInTabSwitcherMode || isTabSwitcherAnimationRunning()) return;
|
| -
|
| - mLocationBarBackgroundOffset.setEmpty();
|
| -
|
| - FrameLayout.LayoutParams locationBarLayoutParams =
|
| - getFrameLayoutParams(mPhoneLocationBar);
|
| - int currentLeftMargin = locationBarLayoutParams.leftMargin;
|
| - int currentWidth = locationBarLayoutParams.width;
|
| -
|
| - float inversePercent = 1f - mUrlExpansionPercent;
|
| - boolean isLocationBarRtl = ApiCompatibilityUtils.isLayoutRtl(mPhoneLocationBar);
|
| - if (ApiCompatibilityUtils.isLayoutRtl(mPhoneLocationBar)) {
|
| - mPhoneLocationBar.setTranslationX(
|
| - ((mUnfocusedLocationBarLayoutLeft + mUnfocusedLocationBarLayoutWidth)
|
| - - (currentLeftMargin + currentWidth)) * inversePercent);
|
| - } else {
|
| - mPhoneLocationBar.setTranslationX(
|
| - (mUnfocusedLocationBarLayoutLeft - currentLeftMargin) * inversePercent);
|
| - mUrlActionsContainer.setTranslationX(-mPhoneLocationBar.getTranslationX());
|
| - }
|
| -
|
| - // Negate the location bar translation to keep the URL action container in the same
|
| - // place during the focus expansion. The check for RTL parity is required because
|
| - // if they do not match then the action container will overlap the URL if we do not
|
| - // allow it to be pushed off.
|
| - if (isLocationBarRtl == ApiCompatibilityUtils.isLayoutRtl(this)) {
|
| - mUrlActionsContainer.setTranslationX(-mPhoneLocationBar.getTranslationX());
|
| - }
|
| -
|
| - mPhoneLocationBar.setUrlFocusChangePercent(mUrlExpansionPercent);
|
| -
|
| - // Ensure the buttons are invisible after focusing the omnibox to prevent them from
|
| - // accepting click events.
|
| - int toolbarButtonVisibility = mUrlExpansionPercent == 1f ? INVISIBLE : VISIBLE;
|
| - mToolbarButtonsContainer.setVisibility(toolbarButtonVisibility);
|
| - if (mHomeButton.getVisibility() != GONE) {
|
| - mHomeButton.setVisibility(toolbarButtonVisibility);
|
| - }
|
| -
|
| - // Force an invalidation of the location bar to properly handle the clipping of the URL
|
| - // bar text as a result of the url action container translations.
|
| - mPhoneLocationBar.invalidate();
|
| - invalidate();
|
| -
|
| - Tab currentTab = getToolbarDataProvider().getTab();
|
| - if (currentTab == null) return;
|
| -
|
| - NewTabPage ntp = getToolbarDataProvider().getNewTabPageForCurrentTab();
|
| - // Explicitly use the focus change percentage here because it applies scroll compensation
|
| - // that only applies during focus animations.
|
| - if (ntp != null && mUrlFocusChangeInProgress) {
|
| - ntp.setUrlFocusChangeAnimationPercent(mUrlFocusChangePercent);
|
| - }
|
| -
|
| - if (!isLocationBarShownInNTP()) {
|
| - // Reset these values in case we transitioned to a different page during the
|
| - // transition.
|
| - resetNtpAnimationValues();
|
| - return;
|
| - }
|
| -
|
| - updateNtpTransitionAnimation(ntp);
|
| - }
|
| -
|
| - private void resetNtpAnimationValues() {
|
| - mLocationBarBackgroundOffset.setEmpty();
|
| - mPhoneLocationBar.setTranslationY(0);
|
| - if (!mUrlFocusChangeInProgress) {
|
| - mToolbarButtonsContainer.setTranslationY(0);
|
| - mHomeButton.setTranslationY(0);
|
| - }
|
| - mToolbarShadow.setAlpha(1f);
|
| - mPhoneLocationBar.setAlpha(1);
|
| - mForceDrawLocationBarBackground = false;
|
| - mUrlBackgroundAlpha = isIncognito()
|
| - || (mUnfocusedLocationBarUsesTransparentBg
|
| - && !mUrlFocusChangeInProgress
|
| - && !mPhoneLocationBar.hasFocus())
|
| - ? LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA : 255;
|
| - setAncestorsShouldClipChildren(true);
|
| - mNtpSearchBoxScrollPercent = UNINITIALIZED_PERCENT;
|
| - }
|
| -
|
| - private void updateNtpTransitionAnimation(NewTabPage ntp) {
|
| - if (mInTabSwitcherMode) return;
|
| -
|
| - setAncestorsShouldClipChildren(mUrlExpansionPercent == 0f);
|
| - mToolbarShadow.setAlpha(0f);
|
| -
|
| - float growthPercent = 0f;
|
| - if (mUrlExpansionPercent == 0f || mUrlExpansionPercent == 1f) {
|
| - growthPercent = 1f - mUrlExpansionPercent;
|
| - } else {
|
| - // During the transition from search box to omnibox, keep the omnibox drawing
|
| - // at the same size of the search box for first 40% of the scroll transition.
|
| - growthPercent = mUrlExpansionPercent <= 0.4f
|
| - ? 1f : Math.min(1f, (1f - mUrlExpansionPercent) * 1.66667f);
|
| - }
|
| -
|
| - int paddingTop = mPhoneLocationBar.getPaddingTop();
|
| - int paddingBottom = mPhoneLocationBar.getPaddingBottom();
|
| -
|
| - ntp.getSearchBoxBounds(mNtpSearchBoxOriginalBounds, mNtpSearchBoxTransformedBounds);
|
| - float halfHeightDifference = (mNtpSearchBoxTransformedBounds.height()
|
| - - (mPhoneLocationBar.getMeasuredHeight() - paddingTop - paddingBottom
|
| - + mLocationBarInsets)) / 2f;
|
| - mPhoneLocationBar.setTranslationY(growthPercent == 0f ? 0 : Math.max(0,
|
| - (mNtpSearchBoxTransformedBounds.top - mPhoneLocationBar.getTop()
|
| - + halfHeightDifference)));
|
| - if (!mUrlFocusChangeInProgress) {
|
| - float searchBoxTranslationY =
|
| - mNtpSearchBoxTransformedBounds.top - mNtpSearchBoxOriginalBounds.top;
|
| - searchBoxTranslationY = Math.min(searchBoxTranslationY, 0);
|
| - mToolbarButtonsContainer.setTranslationY(searchBoxTranslationY);
|
| - mHomeButton.setTranslationY(searchBoxTranslationY);
|
| - }
|
| -
|
| - mLocationBarBackgroundOffset.set(
|
| - (int) ((mNtpSearchBoxTransformedBounds.left - mUrlViewportBounds.left
|
| - - mPhoneLocationBar.getPaddingLeft()) * growthPercent),
|
| - (int) ((-halfHeightDifference - paddingTop) * growthPercent),
|
| - (int) ((mNtpSearchBoxTransformedBounds.right - mUrlViewportBounds.right
|
| - + mPhoneLocationBar.getPaddingRight()) * growthPercent),
|
| - (int) ((halfHeightDifference - paddingBottom + mLocationBarInsets)
|
| - * growthPercent));
|
| -
|
| - // The transparency of the location bar is dependent on how different its size is
|
| - // from the final value. This is based on how much growth is applied between the
|
| - // desired size of the location bar to it's drawn size. The location bar then only
|
| - // starts becoming opaque once the growth is at least half done.
|
| - if (growthPercent >= 0.5f) {
|
| - mPhoneLocationBar.setAlpha(0);
|
| - } else {
|
| - mPhoneLocationBar.setAlpha(1f - growthPercent * 2);
|
| - }
|
| -
|
| - // Go from a transparent url background to a fully opaque one in the first 40% of the
|
| - // scroll transition.
|
| - mUrlBackgroundAlpha =
|
| - mUrlExpansionPercent >= 0.4f ? 255 : (int) ((mUrlExpansionPercent * 2.5f) * 255);
|
| - if (mUrlExpansionPercent == 1f) mUrlBackgroundAlpha = 255;
|
| - mForceDrawLocationBarBackground = mUrlExpansionPercent != 0f;
|
| - }
|
| -
|
| - private void setAncestorsShouldClipChildren(boolean clip) {
|
| - if (!isLocationBarShownInNTP()) return;
|
| - ViewGroup parent = this;
|
| - while (parent != null) {
|
| - parent.setClipChildren(clip);
|
| - if (!(parent.getParent() instanceof ViewGroup)) break;
|
| - if (parent.getId() == android.R.id.content) break;
|
| - parent = (ViewGroup) parent.getParent();
|
| - }
|
| - }
|
| -
|
| - private void drawTabSwitcherFadeAnimation(boolean animationFinished, float progress) {
|
| - setAlpha(progress);
|
| - if (animationFinished) {
|
| - mClipRect = null;
|
| - } else if (mClipRect == null) {
|
| - mClipRect = new Rect();
|
| - }
|
| - if (mClipRect != null) mClipRect.set(0, 0, getWidth(), (int) (getHeight() * progress));
|
| - }
|
| -
|
| - /**
|
| - * When entering and exiting the TabSwitcher mode, we fade out or fade in the browsing
|
| - * mode of the toolbar on top of the TabSwitcher mode version of it. We do this by
|
| - * drawing all of the browsing mode views on top of the android view.
|
| - */
|
| - private void drawTabSwitcherAnimationOverlay(Canvas canvas, float animationProgress) {
|
| - if (!isNativeLibraryReady()) return;
|
| -
|
| - float floatAlpha = 1 - animationProgress;
|
| - int rgbAlpha = (int) (255 * floatAlpha);
|
| - canvas.save();
|
| - canvas.translate(0, -animationProgress * mBackgroundOverlayBounds.height());
|
| - canvas.clipRect(mBackgroundOverlayBounds);
|
| -
|
| - // Draw the background of the view we are leaving.
|
| - mTabSwitcherAnimationBgOverlay.setBounds(
|
| - 0, 0, getMeasuredWidth(), getMeasuredHeight());
|
| - if (isLocationBarShownInNTP()) {
|
| - float ntpTransitionPercentage = mUrlExpansionPercent;
|
| - boolean shouldDrawWhite = ntpTransitionPercentage != 1.0f;
|
| - mTabSwitcherAnimationBgOverlay.setColor(shouldDrawWhite
|
| - ? Color.WHITE : getToolbarColorForVisualState(VisualState.NORMAL));
|
| - }
|
| - mTabSwitcherAnimationBgOverlay.draw(canvas);
|
| -
|
| - float previousAlpha = 0.f;
|
| - if (mHomeButton.getVisibility() != View.GONE) {
|
| - // Draw the New Tab button used in the URL view.
|
| - previousAlpha = mHomeButton.getAlpha();
|
| - mHomeButton.setAlpha(previousAlpha * floatAlpha);
|
| - drawChild(canvas, mHomeButton, SystemClock.uptimeMillis());
|
| - mHomeButton.setAlpha(previousAlpha);
|
| - }
|
| -
|
| - // Draw the location/URL bar.
|
| - previousAlpha = mPhoneLocationBar.getAlpha();
|
| - mPhoneLocationBar.setAlpha(previousAlpha * floatAlpha);
|
| - // If the location bar is now fully transparent, do not bother drawing it.
|
| - if (mPhoneLocationBar.getAlpha() != 0) {
|
| - drawChild(canvas, mPhoneLocationBar, SystemClock.uptimeMillis());
|
| - }
|
| - mPhoneLocationBar.setAlpha(previousAlpha);
|
| -
|
| - // Draw the tab stack button and associated text.
|
| - translateCanvasToView(this, mToolbarButtonsContainer, canvas);
|
| -
|
| - if (mTabSwitcherAnimationTabStackDrawable != null && mToggleTabStackButton != null
|
| - && mUrlExpansionPercent != 1f) {
|
| - // Draw the tab stack button image.
|
| - canvas.save();
|
| - translateCanvasToView(mToolbarButtonsContainer, mToggleTabStackButton, canvas);
|
| -
|
| - int backgroundWidth = mToggleTabStackButton.getDrawable().getIntrinsicWidth();
|
| - int backgroundHeight = mToggleTabStackButton.getDrawable().getIntrinsicHeight();
|
| - int backgroundLeft = (mToggleTabStackButton.getWidth()
|
| - - mToggleTabStackButton.getPaddingLeft()
|
| - - mToggleTabStackButton.getPaddingRight() - backgroundWidth) / 2;
|
| - backgroundLeft += mToggleTabStackButton.getPaddingLeft();
|
| - int backgroundTop = (mToggleTabStackButton.getHeight()
|
| - - mToggleTabStackButton.getPaddingTop()
|
| - - mToggleTabStackButton.getPaddingBottom() - backgroundHeight) / 2;
|
| - backgroundTop += mToggleTabStackButton.getPaddingTop();
|
| - canvas.translate(backgroundLeft, backgroundTop);
|
| -
|
| - mTabSwitcherAnimationTabStackDrawable.setAlpha(rgbAlpha);
|
| - mTabSwitcherAnimationTabStackDrawable.draw(canvas);
|
| - canvas.restore();
|
| - }
|
| -
|
| - // Draw the menu button if necessary.
|
| - if (mTabSwitcherAnimationMenuDrawable != null
|
| - && mUrlExpansionPercent != 1f) {
|
| - mTabSwitcherAnimationMenuDrawable.setBounds(
|
| - mMenuButton.getPaddingLeft(), mMenuButton.getPaddingTop(),
|
| - mMenuButton.getWidth() - mMenuButton.getPaddingRight(),
|
| - mMenuButton.getHeight() - mMenuButton.getPaddingBottom());
|
| - translateCanvasToView(mToolbarButtonsContainer, mMenuButton, canvas);
|
| - mTabSwitcherAnimationMenuDrawable.setAlpha(rgbAlpha);
|
| - mTabSwitcherAnimationMenuDrawable.draw(canvas);
|
| - }
|
| -
|
| - canvas.restore();
|
| - }
|
| -
|
| - @Override
|
| - public void doInvalidate() {
|
| - postInvalidateOnAnimation();
|
| - }
|
| -
|
| - /**
|
| - * Translates the canvas to ensure the specified view's coordinates are at 0, 0.
|
| - *
|
| - * @param from The view the canvas is currently translated to.
|
| - * @param to The view to translate to.
|
| - * @param canvas The canvas to be translated.
|
| - *
|
| - * @throws IllegalArgumentException if {@code from} is not an ancestor of {@code to}.
|
| - */
|
| - private static void translateCanvasToView(View from, View to, Canvas canvas)
|
| - throws IllegalArgumentException {
|
| - assert from != null;
|
| - assert to != null;
|
| - while (to != from) {
|
| - canvas.translate(to.getLeft(), to.getTop());
|
| - if (!(to.getParent() instanceof View)) {
|
| - throw new IllegalArgumentException("View 'to' was not a desendent of 'from'.");
|
| - }
|
| - to = (View) to.getParent();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
|
| - if (child == mPhoneLocationBar) return drawLocationBar(canvas, drawingTime);
|
| - boolean clipped = false;
|
| -
|
| - if (mLocationBarBackground != null
|
| - && ((!mInTabSwitcherMode && !mTabSwitcherModeViews.contains(child))
|
| - || (mInTabSwitcherMode && mBrowsingModeViews.contains(child)))) {
|
| - canvas.save();
|
| - if (mUrlExpansionPercent != 0f && mUrlViewportBounds.top < child.getBottom()) {
|
| - // For other child views, use the inverse clipping of the URL viewport.
|
| - // Only necessary during animations.
|
| - // Hardware mode does not support unioned clip regions, so clip using the
|
| - // appropriate bounds based on whether the child is to the left or right of the
|
| - // location bar.
|
| - boolean isLeft = (child == mNewTabButton || child == mHomeButton)
|
| - ^ LocalizationUtils.isLayoutRtl();
|
| -
|
| - int clipTop = mUrlViewportBounds.top;
|
| - int clipBottom = mUrlViewportBounds.bottom;
|
| - boolean verticalClip = false;
|
| - if (mPhoneLocationBar.getTranslationY() > 0f) {
|
| - clipTop = child.getTop();
|
| - clipBottom = mUrlViewportBounds.top;
|
| - verticalClip = true;
|
| - }
|
| -
|
| - if (isLeft) {
|
| - canvas.clipRect(
|
| - 0, clipTop,
|
| - verticalClip ? child.getMeasuredWidth() : mUrlViewportBounds.left,
|
| - clipBottom);
|
| - } else {
|
| - canvas.clipRect(
|
| - verticalClip ? 0 : mUrlViewportBounds.right,
|
| - clipTop, getMeasuredWidth(), clipBottom);
|
| - }
|
| - }
|
| - clipped = true;
|
| - }
|
| - boolean retVal = super.drawChild(canvas, child, drawingTime);
|
| - if (clipped) canvas.restore();
|
| - return retVal;
|
| - }
|
| -
|
| - private boolean drawLocationBar(Canvas canvas, long drawingTime) {
|
| - boolean clipped = false;
|
| - float locationBarClipLeft = 0;
|
| - float locationBarClipRight = 0;
|
| - float locationBarClipTop = 0;
|
| - float locationBarClipBottom = 0;
|
| -
|
| - if (mLocationBarBackground != null && (!mInTabSwitcherMode || mTextureCaptureMode)) {
|
| - canvas.save();
|
| - int backgroundAlpha = mUrlBackgroundAlpha;
|
| - if (mTabSwitcherModeAnimation != null) {
|
| - // Fade out/in the location bar towards the beginning of the animations to avoid
|
| - // large jumps of stark white.
|
| - backgroundAlpha =
|
| - (int) (Math.pow(mPhoneLocationBar.getAlpha(), 3) * backgroundAlpha);
|
| - } else if (getToolbarDataProvider().isUsingBrandColor()
|
| - && !mBrandColorTransitionActive) {
|
| - int unfocusedAlpha = mUnfocusedLocationBarUsesTransparentBg
|
| - ? LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA : 255;
|
| - backgroundAlpha =
|
| - (int) (mUrlExpansionPercent * (255 - unfocusedAlpha) + unfocusedAlpha);
|
| - }
|
| - mLocationBarBackground.setAlpha(backgroundAlpha);
|
| -
|
| - if (mPhoneLocationBar.getAlpha() > 0 || mForceDrawLocationBarBackground) {
|
| - mLocationBarBackground.setBounds(
|
| - mUrlViewportBounds.left + mLocationBarBackgroundOffset.left,
|
| - mUrlViewportBounds.top + mLocationBarBackgroundOffset.top,
|
| - mUrlViewportBounds.right + mLocationBarBackgroundOffset.right,
|
| - mUrlViewportBounds.bottom + mLocationBarBackgroundOffset.bottom);
|
| - mLocationBarBackground.draw(canvas);
|
| - }
|
| -
|
| - locationBarClipLeft = mUrlViewportBounds.left + mUrlBackgroundPadding.left
|
| - + mLocationBarBackgroundOffset.left;
|
| - locationBarClipRight = mUrlViewportBounds.right - mUrlBackgroundPadding.right
|
| - + mLocationBarBackgroundOffset.right;
|
| -
|
| - // When unexpanded, the location bar's visible content boundaries are inset from the
|
| - // viewport used to draw the background. During expansion transitions, compensation
|
| - // is applied to increase the clip regions such that when the location bar converts
|
| - // to the narrower collapsed layout that the visible content is the same.
|
| - if (mUrlExpansionPercent != 1f) {
|
| - int leftDelta = mUnfocusedLocationBarLayoutLeft - getViewBoundsLeftOfLocationBar();
|
| - int rightDelta = getViewBoundsRightOfLocationBar()
|
| - - mUnfocusedLocationBarLayoutLeft
|
| - - mUnfocusedLocationBarLayoutWidth;
|
| - float inversePercent = 1f - mUrlExpansionPercent;
|
| - locationBarClipLeft += leftDelta * inversePercent;
|
| - locationBarClipRight -= rightDelta * inversePercent;
|
| - }
|
| -
|
| - locationBarClipTop = mUrlViewportBounds.top + mUrlBackgroundPadding.top
|
| - + mLocationBarBackgroundOffset.top;
|
| - locationBarClipBottom = mUrlViewportBounds.bottom - mUrlBackgroundPadding.bottom
|
| - + mLocationBarBackgroundOffset.bottom;
|
| - // Clip the location bar child to the URL viewport calculated in onDraw.
|
| - canvas.clipRect(
|
| - locationBarClipLeft, locationBarClipTop,
|
| - locationBarClipRight, locationBarClipBottom);
|
| - clipped = true;
|
| - }
|
| -
|
| - boolean retVal = super.drawChild(canvas, mPhoneLocationBar, drawingTime);
|
| -
|
| - if (clipped) canvas.restore();
|
| - return retVal;
|
| - }
|
| -
|
| - @Override
|
| - protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
| - mBackgroundOverlayBounds.set(0, 0, w, mToolbarHeightWithoutShadow);
|
| - if (mTabSwitcherAnimationBgOverlay != null) {
|
| - mTabSwitcherAnimationBgOverlay.setBounds(0, 0, w, h);
|
| - }
|
| - super.onSizeChanged(w, h, oldw, oldh);
|
| - }
|
| -
|
| - @Override
|
| - protected void onAttachedToWindow() {
|
| - super.onAttachedToWindow();
|
| - mToolbarShadow = (ImageView) getRootView().findViewById(R.id.toolbar_shadow);
|
| - }
|
| -
|
| - @Override
|
| - public void draw(Canvas canvas) {
|
| - // If capturing a texture of the toolbar, ensure the alpha is set prior to draw(...) being
|
| - // called. The alpha is being used prior to getting to draw(...), so updating the value
|
| - // after this point was having no affect.
|
| - if (mTextureCaptureMode) assert getAlpha() == 1f;
|
| -
|
| - // mClipRect can change in the draw call, so cache this value to ensure the canvas is
|
| - // restored correctly.
|
| - boolean shouldClip = !mTextureCaptureMode && mClipRect != null;
|
| - if (shouldClip) {
|
| - canvas.save();
|
| - canvas.clipRect(mClipRect);
|
| - }
|
| - super.draw(canvas);
|
| - if (shouldClip) {
|
| - canvas.restore();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onStateRestored() {
|
| - if (mToggleTabStackButton != null) mToggleTabStackButton.setClickable(true);
|
| - }
|
| -
|
| - @Override
|
| - public boolean isReadyForTextureCapture() {
|
| - return !(mInTabSwitcherMode || mTabSwitcherModeAnimation != null
|
| - || urlHasFocus() || mUrlFocusChangeInProgress);
|
| - }
|
| -
|
| - @Override
|
| - protected void onNavigatedToDifferentPage() {
|
| - super.onNavigatedToDifferentPage();
|
| - if (FeatureUtilities.isDocumentMode(getContext())) {
|
| - mUrlContainer.setTrailingTextVisible(true);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void setLoadProgress(int progress) {
|
| - super.setLoadProgress(progress);
|
| - if (FeatureUtilities.isDocumentMode(getContext()) && progress == 100) {
|
| - mUrlContainer.setTrailingTextVisible(false);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void finishAnimations() {
|
| - mClipRect = null;
|
| - if (mTabSwitcherModeAnimation != null) {
|
| - mTabSwitcherModeAnimation.end();
|
| - mTabSwitcherModeAnimation = null;
|
| - }
|
| - if (mDelayedTabSwitcherModeAnimation != null) {
|
| - mDelayedTabSwitcherModeAnimation.end();
|
| - mDelayedTabSwitcherModeAnimation = null;
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void getLocationBarContentRect(Rect outRect) {
|
| - if (isLocationBarShownInNTP() && !isFocused()) {
|
| - outRect.setEmpty();
|
| - return;
|
| - }
|
| -
|
| - super.getLocationBarContentRect(outRect);
|
| - }
|
| -
|
| - @Override
|
| - protected void onHomeButtonUpdate(boolean homeButtonEnabled) {
|
| - if (homeButtonEnabled) {
|
| - mHomeButton.setVisibility(urlHasFocus() || mInTabSwitcherMode ? INVISIBLE : VISIBLE);
|
| - if (!mBrowsingModeViews.contains(mHomeButton)) {
|
| - mBrowsingModeViews.add(mHomeButton);
|
| - }
|
| - } else {
|
| - mHomeButton.setVisibility(GONE);
|
| - mBrowsingModeViews.remove(mHomeButton);
|
| - }
|
| - }
|
| -
|
| - private ObjectAnimator createEnterTabSwitcherModeAnimation() {
|
| - ObjectAnimator enterAnimation =
|
| - ObjectAnimator.ofFloat(this, mTabSwitcherModePercentProperty, 1.f);
|
| - enterAnimation.setDuration(TAB_SWITCHER_MODE_ENTER_ANIMATION_DURATION_MS);
|
| - enterAnimation.setInterpolator(new LinearInterpolator());
|
| - enterAnimation.addListener(new AnimatorListenerAdapter() {
|
| - @Override
|
| - public void onAnimationEnd(Animator animation) {
|
| - // This is to deal with the view going invisible when resuming the activity and
|
| - // running this animation. The view is still there and clickable but does not
|
| - // render and only a layout triggers a refresh. See crbug.com/306890.
|
| - if (!mToggleTabStackButton.isEnabled()) requestLayout();
|
| - }
|
| - });
|
| -
|
| - return enterAnimation;
|
| - }
|
| -
|
| - private ObjectAnimator createExitTabSwitcherAnimation(
|
| - final boolean animateNormalToolbar) {
|
| - ObjectAnimator exitAnimation =
|
| - ObjectAnimator.ofFloat(this, mTabSwitcherModePercentProperty, 0.f);
|
| - exitAnimation.setDuration(animateNormalToolbar
|
| - ? TAB_SWITCHER_MODE_EXIT_NORMAL_ANIMATION_DURATION_MS
|
| - : TAB_SWITCHER_MODE_EXIT_FADE_ANIMATION_DURATION_MS);
|
| - exitAnimation.setInterpolator(new LinearInterpolator());
|
| - exitAnimation.addListener(new AnimatorListenerAdapter() {
|
| - @Override
|
| - public void onAnimationEnd(Animator animation) {
|
| - updateViewsForTabSwitcherMode(mInTabSwitcherMode);
|
| - }
|
| - });
|
| -
|
| - return exitAnimation;
|
| - }
|
| -
|
| - private ObjectAnimator createPostExitTabSwitcherAnimation() {
|
| - ObjectAnimator exitAnimation = ObjectAnimator.ofFloat(
|
| - this, View.TRANSLATION_Y, -getHeight(), 0.f);
|
| - exitAnimation.setDuration(TAB_SWITCHER_MODE_POST_EXIT_ANIMATION_DURATION_MS);
|
| - exitAnimation.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - exitAnimation.addListener(new AnimatorListenerAdapter() {
|
| - @Override
|
| - public void onAnimationStart(Animator animation) {
|
| - updateViewsForTabSwitcherMode(mInTabSwitcherMode);
|
| - // On older builds, force an update to ensure the new visuals are used
|
| - // when bringing in the toolbar. crbug.com/404571
|
| - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) {
|
| - requestLayout();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onAnimationEnd(Animator animation) {
|
| - mDelayedTabSwitcherModeAnimation = null;
|
| - updateShadowVisibility(mInTabSwitcherMode);
|
| - updateViewsForTabSwitcherMode(mInTabSwitcherMode);
|
| - }
|
| - });
|
| -
|
| - return exitAnimation;
|
| - }
|
| -
|
| - @Override
|
| - public void setTextureCaptureMode(boolean textureMode) {
|
| - assert mTextureCaptureMode != textureMode;
|
| - mTextureCaptureMode = textureMode;
|
| - if (mTextureCaptureMode) {
|
| - mPreTextureCaptureAlpha = getAlpha();
|
| - setAlpha(1);
|
| - } else {
|
| - setAlpha(mPreTextureCaptureAlpha);
|
| - mPreTextureCaptureAlpha = 1f;
|
| - }
|
| - }
|
| -
|
| - private boolean isTabSwitcherAnimationRunning() {
|
| - return mUIAnimatingTabSwitcherTransition
|
| - || (mTabSwitcherModeAnimation != null && mTabSwitcherModeAnimation.isRunning())
|
| - || (mDelayedTabSwitcherModeAnimation != null
|
| - && mDelayedTabSwitcherModeAnimation.isRunning());
|
| - }
|
| -
|
| - private void updateViewsForTabSwitcherMode(boolean isInTabSwitcherMode) {
|
| - int tabSwitcherViewsVisibility = isInTabSwitcherMode ? VISIBLE : INVISIBLE;
|
| - int browsingViewsVisibility = isInTabSwitcherMode ? INVISIBLE : VISIBLE;
|
| -
|
| - for (View view : mTabSwitcherModeViews) {
|
| - view.setVisibility(tabSwitcherViewsVisibility);
|
| - }
|
| - for (View view : mBrowsingModeViews) {
|
| - view.setVisibility(browsingViewsVisibility);
|
| - }
|
| - getProgressBar().setVisibility(
|
| - isInTabSwitcherMode || isTabSwitcherAnimationRunning() ? INVISIBLE : VISIBLE);
|
| - updateVisualsForToolbarState(isInTabSwitcherMode);
|
| -
|
| - }
|
| -
|
| - @Override
|
| - protected void setContentAttached(boolean attached) {
|
| - updateVisualsForToolbarState(mInTabSwitcherMode);
|
| - }
|
| -
|
| - @Override
|
| - protected void setTabSwitcherMode(
|
| - boolean inTabSwitcherMode, boolean showToolbar, boolean delayAnimation) {
|
| - if (mInTabSwitcherMode == inTabSwitcherMode) return;
|
| -
|
| - finishAnimations();
|
| -
|
| - mDelayingTabSwitcherAnimation = delayAnimation;
|
| -
|
| - if (inTabSwitcherMode) {
|
| - if (mUrlFocusLayoutAnimator != null && mUrlFocusLayoutAnimator.isRunning()) {
|
| - mUrlFocusLayoutAnimator.end();
|
| - mUrlFocusLayoutAnimator = null;
|
| - }
|
| - mNewTabButton.setEnabled(true);
|
| - updateViewsForTabSwitcherMode(true);
|
| - mTabSwitcherModeAnimation = createEnterTabSwitcherModeAnimation();
|
| - } else {
|
| - if (!mDelayingTabSwitcherAnimation) {
|
| - mTabSwitcherModeAnimation = createExitTabSwitcherAnimation(showToolbar);
|
| - }
|
| - mUIAnimatingTabSwitcherTransition = true;
|
| - }
|
| -
|
| - mAnimateNormalToolbar = showToolbar;
|
| - mInTabSwitcherMode = inTabSwitcherMode;
|
| - if (mTabSwitcherModeAnimation != null) mTabSwitcherModeAnimation.start();
|
| -
|
| - if (SysUtils.isLowEndDevice()) finishAnimations();
|
| -
|
| - postInvalidateOnAnimation();
|
| - }
|
| -
|
| - @Override
|
| - protected void onTabSwitcherTransitionFinished() {
|
| - setAlpha(1.f);
|
| - mClipRect = null;
|
| - mUIAnimatingTabSwitcherTransition = false;
|
| - if (!mAnimateNormalToolbar) {
|
| - finishAnimations();
|
| - updateVisualsForToolbarState(mInTabSwitcherMode);
|
| - }
|
| -
|
| - if (mDelayingTabSwitcherAnimation) {
|
| - mDelayingTabSwitcherAnimation = false;
|
| - mDelayedTabSwitcherModeAnimation = createPostExitTabSwitcherAnimation();
|
| - mDelayedTabSwitcherModeAnimation.start();
|
| - } else {
|
| - updateViewsForTabSwitcherMode(mInTabSwitcherMode);
|
| - }
|
| - }
|
| -
|
| - private void updateOverlayDrawables() {
|
| - if (!isNativeLibraryReady()) return;
|
| -
|
| - VisualState overlayState = computeVisualState(false);
|
| - boolean visualStateChanged = mOverlayDrawablesVisualState != overlayState;
|
| -
|
| - if (!visualStateChanged && mVisualState == VisualState.BRAND_COLOR
|
| - && getToolbarDataProvider().getPrimaryColor()
|
| - != mTabSwitcherAnimationBgOverlay.getColor()) {
|
| - visualStateChanged = true;
|
| - }
|
| - if (!visualStateChanged) return;
|
| -
|
| - mOverlayDrawablesVisualState = overlayState;
|
| - mTabSwitcherAnimationBgOverlay.setColor(getToolbarColorForVisualState(
|
| - mOverlayDrawablesVisualState));
|
| -
|
| - if (shouldShowMenuButton()) {
|
| - Resources res = getResources();
|
| - mTabSwitcherAnimationMenuDrawable = ApiCompatibilityUtils.getDrawable(
|
| - res, R.drawable.btn_menu).mutate();
|
| - mTabSwitcherAnimationMenuDrawable.setColorFilter(isIncognito() ? Color.WHITE
|
| - : getResources().getColor(R.color.light_normal_color),
|
| - PorterDuff.Mode.SRC_IN);
|
| - ((BitmapDrawable) mTabSwitcherAnimationMenuDrawable).setGravity(Gravity.CENTER);
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void setOnTabSwitcherClickHandler(OnClickListener listener) {
|
| - mTabSwitcherListener = listener;
|
| - }
|
| -
|
| - @Override
|
| - public void setOnNewTabClickHandler(OnClickListener listener) {
|
| - mNewTabListener = listener;
|
| - }
|
| -
|
| - @Override
|
| - public boolean shouldIgnoreSwipeGesture() {
|
| - return super.shouldIgnoreSwipeGesture() || mUrlExpansionPercent > 0f;
|
| - }
|
| -
|
| - private Property<TextView, Integer> buildUrlScrollProperty(
|
| - final View containerView, final boolean isContainerRtl) {
|
| - // If the RTL-ness of the container view changes during an animation, the scroll values
|
| - // become invalid. If that happens, snap to the ending position and no longer update.
|
| - return new Property<TextView, Integer>(Integer.class, "scrollX") {
|
| - private boolean mRtlStateInvalid;
|
| -
|
| - @Override
|
| - public Integer get(TextView view) {
|
| - return view.getScrollX();
|
| - }
|
| -
|
| - @Override
|
| - public void set(TextView view, Integer scrollX) {
|
| - if (mRtlStateInvalid) return;
|
| - boolean rtl = ApiCompatibilityUtils.isLayoutRtl(containerView);
|
| - if (rtl != isContainerRtl) {
|
| - mRtlStateInvalid = true;
|
| - if (!rtl || mUrlBar.getLayout() != null) {
|
| - scrollX = 0;
|
| - if (rtl) {
|
| - scrollX = (int) view.getLayout().getPrimaryHorizontal(0);
|
| - scrollX -= view.getWidth();
|
| - }
|
| - }
|
| - }
|
| - view.setScrollX(scrollX);
|
| - }
|
| - };
|
| - }
|
| -
|
| - private void populateUrlFocusingAnimatorSet(List<Animator> animators) {
|
| - Animator animator = ObjectAnimator.ofFloat(this, mUrlFocusChangePercentProperty, 1f);
|
| - animator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| -
|
| - for (int i = 0; i < mPhoneLocationBar.getChildCount(); i++) {
|
| - View childView = mPhoneLocationBar.getChildAt(i);
|
| - if (childView == mPhoneLocationBar.getFirstViewVisibleWhenFocused()) break;
|
| - animator = ObjectAnimator.ofFloat(childView, ALPHA, 0);
|
| - animator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| - }
|
| -
|
| - float density = getContext().getResources().getDisplayMetrics().density;
|
| - boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this);
|
| - float toolbarButtonTranslationX = MathUtils.flipSignIf(
|
| - URL_FOCUS_TOOLBAR_BUTTONS_TRANSLATION_X_DP, isRtl) * density;
|
| -
|
| - animator = ObjectAnimator.ofFloat(
|
| - mMenuButton, TRANSLATION_X, toolbarButtonTranslationX);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
|
| - animators.add(animator);
|
| -
|
| - animator = ObjectAnimator.ofFloat(mMenuButton, ALPHA, 0);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
|
| - animators.add(animator);
|
| -
|
| - if (mToggleTabStackButton != null) {
|
| - animator = ObjectAnimator.ofFloat(
|
| - mToggleTabStackButton, TRANSLATION_X, toolbarButtonTranslationX);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
|
| - animators.add(animator);
|
| -
|
| - animator = ObjectAnimator.ofFloat(mToggleTabStackButton, ALPHA, 0);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.FADE_OUT_CURVE);
|
| - animators.add(animator);
|
| - }
|
| - }
|
| -
|
| - private void populateUrlClearFocusingAnimatorSet(List<Animator> animators) {
|
| - Animator animator = ObjectAnimator.ofFloat(this, mUrlFocusChangePercentProperty, 0f);
|
| - animator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| -
|
| - animator = ObjectAnimator.ofFloat(mMenuButton, TRANSLATION_X, 0);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setStartDelay(URL_CLEAR_FOCUS_MENU_DELAY_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| -
|
| - animator = ObjectAnimator.ofFloat(mMenuButton, ALPHA, 1);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setStartDelay(URL_CLEAR_FOCUS_MENU_DELAY_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| -
|
| - if (mToggleTabStackButton != null) {
|
| - animator = ObjectAnimator.ofFloat(mToggleTabStackButton, TRANSLATION_X, 0);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setStartDelay(URL_CLEAR_FOCUS_TABSTACK_DELAY_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| -
|
| - animator = ObjectAnimator.ofFloat(mToggleTabStackButton, ALPHA, 1);
|
| - animator.setDuration(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setStartDelay(URL_CLEAR_FOCUS_TABSTACK_DELAY_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| - }
|
| -
|
| - for (int i = 0; i < mPhoneLocationBar.getChildCount(); i++) {
|
| - View childView = mPhoneLocationBar.getChildAt(i);
|
| - if (childView == mPhoneLocationBar.getFirstViewVisibleWhenFocused()) break;
|
| - animator = ObjectAnimator.ofFloat(childView, ALPHA, 1);
|
| - animator.setStartDelay(URL_FOCUS_TOOLBAR_BUTTONS_DURATION_MS);
|
| - animator.setDuration(URL_CLEAR_FOCUS_MENU_DELAY_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| - }
|
| -
|
| - if (isLocationBarShownInNTP() && mNtpSearchBoxScrollPercent == 0f) return;
|
| -
|
| - if (!FeatureUtilities.isDocumentMode(getContext())
|
| - || mPhoneLocationBar.showingQueryInTheOmnibox()) {
|
| - // The call to getLayout() can return null briefly during text changes, but as it
|
| - // is only needed for RTL calculations, we proceed if the location bar is showing
|
| - // LTR content.
|
| - boolean isLocationBarRtl = ApiCompatibilityUtils.isLayoutRtl(mPhoneLocationBar);
|
| - if (!isLocationBarRtl || mUrlBar.getLayout() != null) {
|
| - int urlBarStartScrollX = 0;
|
| - if (isLocationBarRtl) {
|
| - urlBarStartScrollX = (int) mUrlBar.getLayout().getPrimaryHorizontal(0);
|
| - urlBarStartScrollX -= mUrlBar.getWidth();
|
| - }
|
| -
|
| - // If the scroll position matches the current scroll position, do not trigger
|
| - // this animation as it will cause visible jumps when going from cleared text
|
| - // back to page URLs (despite it continually calling setScrollX with the same
|
| - // number).
|
| - if (mUrlBar.getScrollX() != urlBarStartScrollX) {
|
| - animator = ObjectAnimator.ofInt(
|
| - mUrlBar,
|
| - buildUrlScrollProperty(mPhoneLocationBar, isLocationBarRtl),
|
| - urlBarStartScrollX);
|
| - animator.setDuration(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - animator.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - animators.add(animator);
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onUrlFocusChange(final boolean hasFocus) {
|
| - super.onUrlFocusChange(hasFocus);
|
| -
|
| - triggerUrlFocusAnimation(hasFocus);
|
| -
|
| - TransitionDrawable shadowDrawable = (TransitionDrawable) mToolbarShadow.getDrawable();
|
| - if (hasFocus) {
|
| - shadowDrawable.startTransition(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - } else {
|
| - shadowDrawable.reverseTransition(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - }
|
| - }
|
| -
|
| - private void triggerUrlFocusAnimation(final boolean hasFocus) {
|
| - if (mUrlFocusLayoutAnimator != null && mUrlFocusLayoutAnimator.isRunning()) {
|
| - mUrlFocusLayoutAnimator.cancel();
|
| - mUrlFocusLayoutAnimator = null;
|
| - }
|
| -
|
| - List<Animator> animators = new ArrayList<Animator>();
|
| - if (hasFocus) {
|
| - populateUrlFocusingAnimatorSet(animators);
|
| - } else {
|
| - populateUrlClearFocusingAnimatorSet(animators);
|
| - }
|
| - mUrlFocusLayoutAnimator = new AnimatorSet();
|
| - mUrlFocusLayoutAnimator.playTogether(animators);
|
| -
|
| - mUrlFocusChangeInProgress = true;
|
| - mUrlFocusLayoutAnimator.addListener(new AnimatorListenerAdapter() {
|
| - private boolean mCanceled;
|
| -
|
| - @Override
|
| - public void onAnimationStart(Animator animation) {
|
| - if (!hasFocus) {
|
| - mDisableLocationBarRelayout = true;
|
| - } else {
|
| - mLayoutLocationBarInFocusedMode = true;
|
| - requestLayout();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - public void onAnimationCancel(Animator animation) {
|
| - mCanceled = true;
|
| - }
|
| -
|
| - @Override
|
| - public void onAnimationEnd(Animator animation) {
|
| - if (mCanceled) return;
|
| -
|
| - if (!hasFocus) {
|
| - mDisableLocationBarRelayout = false;
|
| - mLayoutLocationBarInFocusedMode = false;
|
| - requestLayout();
|
| - }
|
| - mPhoneLocationBar.finishUrlFocusChange(hasFocus);
|
| - mUrlFocusChangeInProgress = false;
|
| - }
|
| - });
|
| - mUrlFocusLayoutAnimator.start();
|
| - }
|
| -
|
| - @Override
|
| - protected boolean shouldShowMenuButton() {
|
| - // Even in Document mode, the toolbar menu button will be shown while on the NTP. This
|
| - // allows the menu to translate off the screen on scroll to match the tabbed behavior.
|
| - if (mVisualState == VisualState.NEW_TAB_NORMAL) return true;
|
| -
|
| - return !mPhoneLocationBar.showMenuButtonInOmnibox() && super.shouldShowMenuButton();
|
| - }
|
| -
|
| - @Override
|
| - protected void updateTabCountVisuals(int numberOfTabs) {
|
| - if (mHomeButton != null) mHomeButton.setEnabled(true);
|
| -
|
| - if (mToggleTabStackButton == null) return;
|
| -
|
| - mToggleTabStackButton.setEnabled(numberOfTabs >= 1);
|
| - mToggleTabStackButton.setContentDescription(
|
| - getResources().getString(R.string.accessibility_toolbar_btn_tabswitcher_toggle,
|
| - numberOfTabs));
|
| - mTabSwitcherButtonDrawableLight.updateForTabCount(numberOfTabs, isIncognito());
|
| - mTabSwitcherButtonDrawable.updateForTabCount(numberOfTabs, isIncognito());
|
| -
|
| - boolean useTabStackDrawableLight = isIncognito();
|
| - if (mTabSwitcherAnimationTabStackDrawable == null
|
| - || mIsOverlayTabStackDrawableLight != useTabStackDrawableLight) {
|
| - mTabSwitcherAnimationTabStackDrawable =
|
| - TabSwitcherDrawable.createTabSwitcherDrawable(
|
| - getResources(), useTabStackDrawableLight);
|
| - int[] stateSet = {android.R.attr.state_enabled};
|
| - mTabSwitcherAnimationTabStackDrawable.setState(stateSet);
|
| - mTabSwitcherAnimationTabStackDrawable.setBounds(
|
| - mToggleTabStackButton.getDrawable().getBounds());
|
| - mIsOverlayTabStackDrawableLight = useTabStackDrawableLight;
|
| - }
|
| -
|
| - if (mTabSwitcherAnimationTabStackDrawable != null) {
|
| - mTabSwitcherAnimationTabStackDrawable.updateForTabCount(
|
| - numberOfTabs, isIncognito());
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - protected void onTabContentViewChanged() {
|
| - super.onTabContentViewChanged();
|
| - updateNtpAnimationState();
|
| - updateVisualsForToolbarState(mInTabSwitcherMode);
|
| - }
|
| -
|
| - @Override
|
| - protected void onTabOrModelChanged() {
|
| - super.onTabOrModelChanged();
|
| - updateNtpAnimationState();
|
| - updateVisualsForToolbarState(mInTabSwitcherMode);
|
| - }
|
| -
|
| - private static boolean isVisualStateValidForBrandColorTransition(VisualState state) {
|
| - return state == VisualState.NORMAL || state == VisualState.BRAND_COLOR;
|
| - }
|
| -
|
| - @Override
|
| - protected void onPrimaryColorChanged() {
|
| - if (!FeatureUtilities.isDocumentMode(getContext())) return;
|
| -
|
| - super.onPrimaryColorChanged();
|
| - if (mBrandColorTransitionActive) mBrandColorTransitionAnimation.cancel();
|
| - if (!isVisualStateValidForBrandColorTransition(mVisualState)) {
|
| - return;
|
| - }
|
| - final int initialColor = mToolbarBackground.getColor();
|
| - final int finalColor = getToolbarDataProvider().getPrimaryColor();
|
| - if (initialColor == finalColor) return;
|
| - boolean shouldUseOpaque = BrandColorUtils.shouldUseOpaqueTextboxBackground(finalColor);
|
| - final int initialAlpha = mUrlBackgroundAlpha;
|
| - final int finalAlpha =
|
| - shouldUseOpaque ? 255 : LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA;
|
| - final boolean shouldAnimateAlpha = initialAlpha != finalAlpha;
|
| - mBrandColorTransitionAnimation = ValueAnimator.ofFloat(0, 1)
|
| - .setDuration(BRAND_COLOR_TRANSITION_DURATION_MS);
|
| - mBrandColorTransitionAnimation.setInterpolator(BakedBezierInterpolator.TRANSFORM_CURVE);
|
| - mBrandColorTransitionAnimation.addUpdateListener(new AnimatorUpdateListener() {
|
| - @Override
|
| - public void onAnimationUpdate(ValueAnimator animation) {
|
| - float fraction = animation.getAnimatedFraction();
|
| - int red = (int) (Color.red(initialColor)
|
| - + fraction * (Color.red(finalColor) - Color.red(initialColor)));
|
| - int green = (int) (Color.green(initialColor)
|
| - + fraction * (Color.green(finalColor) - Color.green(initialColor)));
|
| - int blue = (int) (Color.blue(initialColor)
|
| - + fraction * (Color.blue(finalColor) - Color.blue(initialColor)));
|
| - if (shouldAnimateAlpha) {
|
| - mUrlBackgroundAlpha =
|
| - (int) (initialAlpha + fraction * (finalAlpha - initialAlpha));
|
| - }
|
| - updateToolbarBackground(Color.rgb(red, green, blue));
|
| - }
|
| - });
|
| - mBrandColorTransitionAnimation.addListener(new AnimatorListenerAdapter() {
|
| - @Override
|
| - public void onAnimationEnd(Animator animation) {
|
| - mBrandColorTransitionActive = false;
|
| - updateVisualsForToolbarState(mInTabSwitcherMode);
|
| - }
|
| - });
|
| - mBrandColorTransitionAnimation.start();
|
| - mBrandColorTransitionActive = true;
|
| - }
|
| -
|
| - private void updateNtpAnimationState() {
|
| - // Store previous NTP scroll before calling reset as that clears this value.
|
| - boolean wasShowingNtp = mVisibleNewTabPage != null;
|
| - float previousNtpScrollPercent = mNtpSearchBoxScrollPercent;
|
| -
|
| - resetNtpAnimationValues();
|
| - if (mVisibleNewTabPage != null) {
|
| - mVisibleNewTabPage.setSearchBoxScrollListener(null);
|
| - mVisibleNewTabPage = null;
|
| - }
|
| - mVisibleNewTabPage = getToolbarDataProvider().getNewTabPageForCurrentTab();
|
| - if (mVisibleNewTabPage != null && mVisibleNewTabPage.isLocationBarShownInNTP()) {
|
| - mVisibleNewTabPage.setSearchBoxScrollListener(this);
|
| - requestLayout();
|
| - } else if (wasShowingNtp) {
|
| - // Convert the previous NTP scroll percentage to URL focus percentage because that
|
| - // will give a nicer transition animation from the expanded NTP omnibox to the
|
| - // collapsed normal omnibox on other non-NTP pages.
|
| - if (!mInTabSwitcherMode && previousNtpScrollPercent > 0f) {
|
| - mUrlFocusChangePercent =
|
| - Math.max(previousNtpScrollPercent, mUrlFocusChangePercent);
|
| - triggerUrlFocusAnimation(false);
|
| - }
|
| - requestLayout();
|
| - }
|
| - }
|
| -
|
| - @Override
|
| - protected void onDefaultSearchEngineChanged() {
|
| - super.onDefaultSearchEngineChanged();
|
| - // Post an update for the toolbar state, which will allow all other listeners
|
| - // for the search engine change to update before we check on the state of the
|
| - // world for a UI update.
|
| - // TODO(tedchoc): Move away from updating based on the search engine change and instead
|
| - // add the toolbar as a listener to the NewTabPage and udpate only when
|
| - // it notifies the listeners that it has changed it's state.
|
| - post(new Runnable() {
|
| - @Override
|
| - public void run() {
|
| - updateVisualsForToolbarState(mInTabSwitcherMode);
|
| - updateNtpAnimationState();
|
| - }
|
| - });
|
| - }
|
| -
|
| - @Override
|
| - protected void handleFindToolbarStateChange(boolean showing) {
|
| - setVisibility(showing ? View.GONE : View.VISIBLE);
|
| - TransitionDrawable shadowDrawable = (TransitionDrawable) mToolbarShadow.getDrawable();
|
| - if (showing) {
|
| - shadowDrawable.startTransition(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - } else {
|
| - shadowDrawable.reverseTransition(URL_FOCUS_CHANGE_ANIMATION_DURATION_MS);
|
| - }
|
| - }
|
| -
|
| - private boolean isLocationBarShownInNTP() {
|
| - NewTabPage ntp = getToolbarDataProvider().getNewTabPageForCurrentTab();
|
| - return ntp != null && ntp.isLocationBarShownInNTP();
|
| - }
|
| -
|
| - private void updateShadowVisibility(boolean isInTabSwitcherMode) {
|
| - boolean shouldDrawShadow = !isInTabSwitcherMode && !isTabSwitcherAnimationRunning();
|
| - int shadowVisibility = shouldDrawShadow ? View.VISIBLE : View.INVISIBLE;
|
| -
|
| - if (mToolbarShadow.getVisibility() != shadowVisibility) {
|
| - mToolbarShadow.setVisibility(shadowVisibility);
|
| - }
|
| - }
|
| -
|
| - private VisualState computeVisualState(boolean isInTabSwitcherMode) {
|
| - if (isInTabSwitcherMode && isIncognito()) return VisualState.TAB_SWITCHER_INCOGNITO;
|
| - if (isInTabSwitcherMode && !isIncognito()) return VisualState.TAB_SWITCHER_NORMAL;
|
| - if (isLocationBarShownInNTP()) return VisualState.NEW_TAB_NORMAL;
|
| - if (isIncognito()) return VisualState.INCOGNITO;
|
| - if (getToolbarDataProvider().isUsingBrandColor()) return VisualState.BRAND_COLOR;
|
| - return VisualState.NORMAL;
|
| - }
|
| -
|
| - private void updateVisualsForToolbarState(boolean isInTabSwitcherMode) {
|
| - final boolean isIncognito = isIncognito();
|
| -
|
| - VisualState newVisualState = computeVisualState(isInTabSwitcherMode);
|
| -
|
| - // If we are navigating to or from a brand color, allow the transition animation
|
| - // to run to completion as it will handle the triggering this path again and committing
|
| - // the proper visual state when it finishes. Brand color transitions are only valid
|
| - // between normal non-incognito pages and brand color pages, so if the visual states
|
| - // do not match then cancel the animation below.
|
| - if (mBrandColorTransitionActive
|
| - && isVisualStateValidForBrandColorTransition(mVisualState)
|
| - && isVisualStateValidForBrandColorTransition(newVisualState)) {
|
| - return;
|
| - } else if (mBrandColorTransitionAnimation != null
|
| - && mBrandColorTransitionAnimation.isRunning()) {
|
| - mBrandColorTransitionAnimation.cancel();
|
| - }
|
| -
|
| - boolean visualStateChanged = mVisualState != newVisualState;
|
| -
|
| - int currentPrimaryColor = getToolbarDataProvider().getPrimaryColor();
|
| - if (mVisualState == VisualState.BRAND_COLOR && !visualStateChanged) {
|
| - boolean useLightToolbarDrawables =
|
| - BrandColorUtils.shouldUseLightDrawablesForToolbar(currentPrimaryColor);
|
| - boolean unfocusedLocationBarUsesTransparentBg =
|
| - !BrandColorUtils.shouldUseOpaqueTextboxBackground(currentPrimaryColor);
|
| - if (useLightToolbarDrawables != mUseLightToolbarDrawables
|
| - || unfocusedLocationBarUsesTransparentBg
|
| - != mUnfocusedLocationBarUsesTransparentBg) {
|
| - visualStateChanged = true;
|
| - } else {
|
| - updateToolbarBackground(VisualState.BRAND_COLOR);
|
| - }
|
| - }
|
| -
|
| - mVisualState = newVisualState;
|
| -
|
| - updateOverlayDrawables();
|
| - updateShadowVisibility(isInTabSwitcherMode);
|
| - if (!visualStateChanged) {
|
| - if (mVisualState == VisualState.NEW_TAB_NORMAL) {
|
| - updateNtpTransitionAnimation(
|
| - getToolbarDataProvider().getNewTabPageForCurrentTab());
|
| - }
|
| - return;
|
| - }
|
| -
|
| - mUseLightToolbarDrawables = false;
|
| - mUnfocusedLocationBarUsesTransparentBg = false;
|
| - mUrlBackgroundAlpha = 255;
|
| - int progressBarResource = R.drawable.progress_bar;
|
| - updateToolbarBackground(mVisualState);
|
| - if (isInTabSwitcherMode) {
|
| - mUseLightToolbarDrawables = true;
|
| - mUrlBackgroundAlpha = LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA;
|
| - progressBarResource = R.drawable.progress_bar_white;
|
| - } else if (isIncognito()) {
|
| - mUseLightToolbarDrawables = true;
|
| - mUrlBackgroundAlpha = LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA;
|
| - progressBarResource = R.drawable.progress_bar_white;
|
| - } else if (mVisualState == VisualState.BRAND_COLOR) {
|
| - mUseLightToolbarDrawables =
|
| - BrandColorUtils.shouldUseLightDrawablesForToolbar(currentPrimaryColor);
|
| - mUnfocusedLocationBarUsesTransparentBg =
|
| - !BrandColorUtils.shouldUseOpaqueTextboxBackground(currentPrimaryColor);
|
| - mUrlBackgroundAlpha = mUnfocusedLocationBarUsesTransparentBg
|
| - ? LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA : 255;
|
| - progressBarResource = mUseLightToolbarDrawables
|
| - ? R.drawable.progress_bar_white : R.drawable.progress_bar;
|
| - } else {
|
| - mUseLightToolbarDrawables = false;
|
| - mUrlBackgroundAlpha = 255;
|
| - progressBarResource = R.drawable.progress_bar;
|
| - }
|
| -
|
| - getProgressBar().setProgressDrawable(
|
| - ApiCompatibilityUtils.getDrawable(getResources(), progressBarResource));
|
| -
|
| - if (mToggleTabStackButton != null) {
|
| - mToggleTabStackButton.setImageDrawable(mUseLightToolbarDrawables
|
| - ? mTabSwitcherButtonDrawableLight : mTabSwitcherButtonDrawable);
|
| - }
|
| -
|
| - ColorStateList dark = getResources().getColorStateList(R.color.dark_mode_tint);
|
| - ColorStateList white = getResources().getColorStateList(R.color.light_mode_tint);
|
| - if (shouldShowMenuButton()) {
|
| - mMenuButton.setTint(mUseLightToolbarDrawables ? white : dark);
|
| - }
|
| - if (mHomeButton.getVisibility() != GONE) {
|
| - mHomeButton.setTint(mUseLightToolbarDrawables ? white : dark);
|
| - }
|
| -
|
| - mPhoneLocationBar.updateVisualsForState();
|
| -
|
| - // We update the alpha before comparing the visual state as we need to change
|
| - // it's value when entering and exiting TabSwitcher mode.
|
| - if (isLocationBarShownInNTP() && !isInTabSwitcherMode) {
|
| - updateNtpTransitionAnimation(
|
| - getToolbarDataProvider().getNewTabPageForCurrentTab());
|
| - }
|
| -
|
| - if (isInTabSwitcherMode) mNewTabButton.setIsIncognito(isIncognito);
|
| -
|
| - CharSequence newTabContentDescription = getResources().getText(
|
| - isIncognito ? R.string.accessibility_toolbar_btn_new_incognito_tab :
|
| - R.string.accessibility_toolbar_btn_new_tab);
|
| - if (mNewTabButton != null
|
| - && !newTabContentDescription.equals(mNewTabButton.getContentDescription())) {
|
| - mNewTabButton.setContentDescription(newTabContentDescription);
|
| - }
|
| -
|
| - getMenuButton().setVisibility(shouldShowMenuButton() ? View.VISIBLE : View.GONE);
|
| - }
|
| -
|
| - @Override
|
| - public LocationBar getLocationBar() {
|
| - return mPhoneLocationBar;
|
| - }
|
| -}
|
| -
|
|
|