| Index: chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
|
| diff --git a/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java b/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a2f9629bc53217d9e9dc83a18c644ffbe0b531c3
|
| --- /dev/null
|
| +++ b/chrome/android/java_staging/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackAnimation.java
|
| @@ -0,0 +1,437 @@
|
| +// 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.compositor.layouts.phone.stack;
|
| +
|
| +import static org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.AnimatableAnimation.addAnimation;
|
| +import static org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab.Property.DISCARD_AMOUNT;
|
| +import static org.chromium.chrome.browser.compositor.layouts.phone.stack.StackTab.Property.SCROLL_OFFSET;
|
| +
|
| +import android.view.animation.Interpolator;
|
| +
|
| +import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation;
|
| +import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation.Animatable;
|
| +import org.chromium.chrome.browser.compositor.layouts.Layout.Orientation;
|
| +import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
|
| +import org.chromium.ui.interpolators.BakedBezierInterpolator;
|
| +
|
| +/**
|
| + * A factory that builds animations for the tab stack.
|
| + */
|
| +public abstract class StackAnimation {
|
| + public enum OverviewAnimationType {
|
| + ENTER_STACK,
|
| + NEW_TAB_OPENED,
|
| + TAB_FOCUSED,
|
| + VIEW_MORE,
|
| + REACH_TOP,
|
| + // Commit/uncommit tab discard animations
|
| + DISCARD,
|
| + DISCARD_ALL,
|
| + UNDISCARD,
|
| + // Start pinch animation un-tilt all the tabs.
|
| + START_PINCH,
|
| + // Special animation
|
| + FULL_ROLL,
|
| + // Used for when the current state of the system is not animating
|
| + NONE,
|
| + }
|
| +
|
| + public static final float SCALE_AMOUNT = 0.90f;
|
| + protected static final float INITIAL_ALPHA_AMOUNT = 0.1f;
|
| + protected static final float INITIAL_SCALE_AMOUNT = 0.75f;
|
| +
|
| + protected static final int ENTER_STACK_TOOLBAR_ALPHA_DURATION = 100;
|
| + protected static final int ENTER_STACK_TOOLBAR_ALPHA_DELAY = 100;
|
| + protected static final int ENTER_STACK_ANIMATION_DURATION = 300;
|
| + protected static final int ENTER_STACK_RESIZE_DELAY = 10;
|
| + protected static final int ENTER_STACK_BORDER_ALPHA_DURATION = 200;
|
| + protected static final int ENTER_STACK_BORDER_ALPHA_DELAY = 0;
|
| + protected static final float ENTER_STACK_SIZE_RATIO = 0.35f;
|
| +
|
| + protected static final int TAB_FOCUSED_TOOLBAR_ALPHA_DURATION = 250;
|
| + protected static final int TAB_FOCUSED_TOOLBAR_ALPHA_DELAY = 0;
|
| + protected static final int TAB_FOCUSED_ANIMATION_DURATION = 400;
|
| + protected static final int TAB_FOCUSED_Y_STACK_DURATION = 200;
|
| + protected static final int TAB_FOCUSED_BORDER_ALPHA_DURATION = 200;
|
| + protected static final int TAB_FOCUSED_BORDER_ALPHA_DELAY = 0;
|
| + protected static final int TAB_FOCUSED_MAX_DELAY = 100;
|
| +
|
| + protected static final int VIEW_MORE_ANIMATION_DURATION = 400;
|
| + protected static final float VIEW_MORE_SIZE_RATIO = 0.75f;
|
| + protected static final int VIEW_MORE_MIN_SIZE = 200;
|
| +
|
| + protected static final int REACH_TOP_ANIMATION_DURATION = 400;
|
| +
|
| + protected static final int UNDISCARD_ANIMATION_DURATION = 150;
|
| +
|
| + protected static final int TAB_OPENED_ANIMATION_DURATION = 300;
|
| + protected static final int TAB_OPENED_BORDER_ALPHA_DURATION = 100;
|
| + protected static final int TAB_OPENED_BORDER_ALPHA_DELAY = 100;
|
| +
|
| + protected static final int DISCARD_ANIMATION_DURATION = 150;
|
| + protected static final int TAB_REORDER_DURATION = 500;
|
| + protected static final int TAB_REORDER_START_SPAN = 400;
|
| +
|
| + protected static final int START_PINCH_ANIMATION_DURATION = 75;
|
| +
|
| + protected static final int FULL_ROLL_ANIMATION_DURATION = 1000;
|
| +
|
| + protected final float mWidth;
|
| + protected final float mHeight;
|
| + protected final float mHeightMinusTopControls;
|
| + protected final float mBorderTopHeight;
|
| + protected final float mBorderTopOpaqueHeight;
|
| + protected final float mBorderLeftWidth;
|
| +
|
| + /**
|
| + * Protected constructor.
|
| + *
|
| + * @param width The width of the layout in dp.
|
| + * @param height The height of the layout in dp.
|
| + * @param heightMinusTopControls The height of the layout minus the top controls in dp.
|
| + * @param borderFramePaddingTop The top padding of the border frame in dp.
|
| + * @param borderFramePaddingTopOpaque The opaque top padding of the border frame in dp.
|
| + * @param borderFramePaddingLeft The left padding of the border frame in dp.
|
| + */
|
| + protected StackAnimation(float width, float height, float heightMinusTopControls,
|
| + float borderFramePaddingTop, float borderFramePaddingTopOpaque,
|
| + float borderFramePaddingLeft) {
|
| + mWidth = width;
|
| + mHeight = height;
|
| + mHeightMinusTopControls = heightMinusTopControls;
|
| +
|
| + mBorderTopHeight = borderFramePaddingTop;
|
| + mBorderTopOpaqueHeight = borderFramePaddingTopOpaque;
|
| + mBorderLeftWidth = borderFramePaddingLeft;
|
| + }
|
| +
|
| + /**
|
| + * The factory method that creates the particular factory method based on the orientation
|
| + * parameter.
|
| + *
|
| + * @param width The width of the layout in dp.
|
| + * @param height The height of the layout in dp.
|
| + * @param heightMinusTopControls The height of the layout minus the top controls in dp.
|
| + * @param borderFramePaddingTop The top padding of the border frame in dp.
|
| + * @param borderFramePaddingTopOpaque The opaque top padding of the border frame in dp.
|
| + * @param borderFramePaddingLeft The left padding of the border frame in dp.
|
| + * @param orientation The orientation that will be used to create the
|
| + * appropriate {@link StackAnimation}.
|
| + * @return The TabSwitcherAnimationFactory instance.
|
| + */
|
| + public static StackAnimation createAnimationFactory(float width, float height,
|
| + float heightMinusTopControls, float borderFramePaddingTop,
|
| + float borderFramePaddingTopOpaque, float borderFramePaddingLeft, int orientation) {
|
| + StackAnimation factory = null;
|
| + switch (orientation) {
|
| + case Orientation.LANDSCAPE:
|
| + factory = new StackAnimationLandscape(width, height, heightMinusTopControls,
|
| + borderFramePaddingTop, borderFramePaddingTopOpaque, borderFramePaddingLeft);
|
| + break;
|
| + case Orientation.PORTRAIT:
|
| + default:
|
| + factory = new StackAnimationPortrait(width, height, heightMinusTopControls,
|
| + borderFramePaddingTop, borderFramePaddingTopOpaque, borderFramePaddingLeft);
|
| + break;
|
| + }
|
| +
|
| + return factory;
|
| + }
|
| +
|
| + /**
|
| + * The wrapper method responsible for delegating the animations request to the appropriate
|
| + * helper method. Not all parameters are used for each request.
|
| + *
|
| + * @param type The type of animation to be created. This is what
|
| + * determines which helper method is called.
|
| + * @param tabs The tabs that make up the current stack that will
|
| + * be animated.
|
| + * @param focusIndex The index of the tab that is the focus of this animation.
|
| + * @param sourceIndex The index of the tab that triggered this animation.
|
| + * @param spacing The default spacing between the tabs.
|
| + * @param scrollOffset The scroll offset in the current orientation.
|
| + * @param warpSize The warp size of the transform from scroll space to screen space.
|
| + * @param discardRange The range of the discard amount value.
|
| + * @return The resulting TabSwitcherAnimation that will animate the tabs.
|
| + */
|
| + public ChromeAnimation<?> createAnimatorSetForType(OverviewAnimationType type, StackTab[] tabs,
|
| + int focusIndex, int sourceIndex, int spacing, float scrollOffset, float warpSize,
|
| + float discardRange) {
|
| + ChromeAnimation<?> set = null;
|
| +
|
| + if (tabs != null) {
|
| + switch (type) {
|
| + case ENTER_STACK:
|
| + set = createEnterStackAnimatorSet(tabs, focusIndex, spacing, warpSize);
|
| + break;
|
| + case TAB_FOCUSED:
|
| + set = createTabFocusedAnimatorSet(tabs, focusIndex, spacing, warpSize);
|
| + break;
|
| + case VIEW_MORE:
|
| + set = createViewMoreAnimatorSet(tabs, sourceIndex);
|
| + break;
|
| + case REACH_TOP:
|
| + set = createReachTopAnimatorSet(tabs, warpSize);
|
| + break;
|
| + case DISCARD:
|
| + // Purposeful fall through
|
| + case DISCARD_ALL:
|
| + // Purposeful fall through
|
| + case UNDISCARD:
|
| + set = createUpdateDiscardAnimatorSet(tabs, spacing, warpSize, discardRange);
|
| + break;
|
| + case NEW_TAB_OPENED:
|
| + set = createNewTabOpenedAnimatorSet(tabs, focusIndex, discardRange);
|
| + break;
|
| + case START_PINCH:
|
| + set = createStartPinchAnimatorSet(tabs);
|
| + break;
|
| + case FULL_ROLL:
|
| + set = createFullRollAnimatorSet(tabs);
|
| + break;
|
| + case NONE:
|
| + break;
|
| + }
|
| + }
|
| + return set;
|
| + }
|
| +
|
| + protected abstract float getScreenSizeInScrollDirection();
|
| +
|
| + protected abstract float getScreenPositionInScrollDirection(StackTab tab);
|
| +
|
| + protected abstract void addTiltScrollAnimation(ChromeAnimation<Animatable<?>> set,
|
| + LayoutTab tab, float end, int duration, int startTime);
|
| +
|
| + /**
|
| + * @return The direction the tab should come from as it is created. -1 means top/right, 1 means
|
| + * bottom/left.
|
| + */
|
| + protected abstract int getTabCreationDirection();
|
| +
|
| + /**
|
| + * Responsible for generating the animations that shows the stack
|
| + * being entered.
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the
|
| + * tabs that will be affected by the TabSwitcherAnimation.
|
| + * @param focusIndex The focused index. In this case, this is the index of
|
| + * the tab that was being viewed before entering the stack.
|
| + * @param spacing The default spacing between tabs.
|
| + * @param warpSize The warp size of the transform from scroll space to screen space.
|
| + * @return The TabSwitcherAnimation instance that will tween the
|
| + * tabs to create the appropriate animation.
|
| + */
|
| + protected abstract ChromeAnimation<?> createEnterStackAnimatorSet(
|
| + StackTab[] tabs, int focusIndex, int spacing, float warpSize);
|
| +
|
| + /**
|
| + * Responsible for generating the animations that shows a tab being
|
| + * focused (the stack is being left).
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the
|
| + * tabs that will be affected by the TabSwitcherAnimation.
|
| + * @param focusIndex The focused index. In this case, this is the index of
|
| + * the tab clicked and is being brought up to view.
|
| + * @param spacing The default spacing between tabs.
|
| + * @param warpSize The warp size of the transform from scroll space to screen space.
|
| + * @return The TabSwitcherAnimation instance that will tween the
|
| + * tabs to create the appropriate animation.
|
| + */
|
| + protected abstract ChromeAnimation<?> createTabFocusedAnimatorSet(
|
| + StackTab[] tabs, int focusIndex, int spacing, float warpSize);
|
| +
|
| + /**
|
| + * Responsible for generating the animations that Shows more of the selected tab.
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the
|
| + * tabs that will be affected by the TabSwitcherAnimation.
|
| + * @param selectedIndex The selected index. In this case, this is the index of
|
| + * the tab clicked and is being brought up to view.
|
| + * @return The TabSwitcherAnimation instance that will tween the
|
| + * tabs to create the appropriate animation.
|
| + */
|
| + protected abstract ChromeAnimation<?> createViewMoreAnimatorSet(
|
| + StackTab[] tabs, int selectedIndex);
|
| +
|
| + /**
|
| + * Responsible for generating the TabSwitcherAnimation that moves the tabs up so they
|
| + * reach the to top the screen.
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the
|
| + * tabs that will be affected by the TabSwitcherAnimation.
|
| + * @param warpSize The warp size of the transform from scroll space to screen space.
|
| + * @return The TabSwitcherAnimation instance that will tween the
|
| + * tabs to create the appropriate animation.
|
| + */
|
| + protected abstract ChromeAnimation<?> createReachTopAnimatorSet(
|
| + StackTab[] tabs, float warpSize);
|
| +
|
| + /**
|
| + * Responsible for generating the animations that moves the tabs back in from
|
| + * discard attempt or commit the current discard (if any). It also re-even the tabs
|
| + * if one of then is removed.
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the
|
| + * tabs that will be affected by the TabSwitcherAnimation.
|
| + * @param spacing The default spacing between tabs.
|
| + * @param warpSize The warp size of the transform from scroll space to screen space.
|
| + * @param discardRange The maximum value the discard amount.
|
| + * @return The TabSwitcherAnimation instance that will tween the
|
| + * tabs to create the appropriate animation.
|
| + */
|
| + protected ChromeAnimation<?> createUpdateDiscardAnimatorSet(
|
| + StackTab[] tabs, int spacing, float warpSize, float discardRange) {
|
| + ChromeAnimation<Animatable<?>> set = new ChromeAnimation<Animatable<?>>();
|
| +
|
| + int dyingTabsCount = 0;
|
| + float firstDyingTabOffset = 0;
|
| + for (int i = 0; i < tabs.length; ++i) {
|
| + StackTab tab = tabs[i];
|
| +
|
| + addTiltScrollAnimation(set, tab.getLayoutTab(), 0.0f, UNDISCARD_ANIMATION_DURATION, 0);
|
| +
|
| + if (tab.isDying()) {
|
| + dyingTabsCount++;
|
| + if (dyingTabsCount == 1) {
|
| + firstDyingTabOffset = getScreenPositionInScrollDirection(tab);
|
| + }
|
| + }
|
| + }
|
| +
|
| + Interpolator interpolator = BakedBezierInterpolator.FADE_OUT_CURVE;
|
| +
|
| + int newIndex = 0;
|
| + for (int i = 0; i < tabs.length; ++i) {
|
| + StackTab tab = tabs[i];
|
| + long startTime = (long) Math.max(0, TAB_REORDER_START_SPAN
|
| + / getScreenSizeInScrollDirection()
|
| + * (getScreenPositionInScrollDirection(tab) - firstDyingTabOffset));
|
| + if (tab.isDying()) {
|
| + float discard = tab.getDiscardAmount();
|
| + if (discard == 0.0f) discard = isDefaultDiscardDirectionPositive() ? 0.0f : -0.0f;
|
| + float s = Math.copySign(1.0f, discard);
|
| + long duration = (long) (DISCARD_ANIMATION_DURATION
|
| + * (1.0f - Math.abs(discard / discardRange)));
|
| + addAnimation(set, tab, DISCARD_AMOUNT, discard, discardRange * s, duration,
|
| + startTime, false, interpolator);
|
| + } else {
|
| + if (tab.getDiscardAmount() != 0.f) {
|
| + addAnimation(set, tab, DISCARD_AMOUNT, tab.getDiscardAmount(), 0.0f,
|
| + UNDISCARD_ANIMATION_DURATION, 0);
|
| + }
|
| +
|
| + float newScrollOffset = StackTab.screenToScroll(spacing * newIndex, warpSize);
|
| +
|
| + // If the tab is not dying we want to readjust it's position
|
| + // based on the new spacing requirements. For a fully discarded tab, just
|
| + // put it in the right place.
|
| + if (tab.getDiscardAmount() >= discardRange) {
|
| + tab.setScrollOffset(newScrollOffset);
|
| + tab.setScale(SCALE_AMOUNT);
|
| + } else {
|
| + float start = tab.getScrollOffset();
|
| + if (start != newScrollOffset) {
|
| + addAnimation(set, tab, SCROLL_OFFSET, start, newScrollOffset,
|
| + TAB_REORDER_DURATION, startTime);
|
| + }
|
| + }
|
| + newIndex++;
|
| + }
|
| + }
|
| + return set;
|
| + }
|
| +
|
| + /**
|
| + * This is used to determine the discard direction when user just clicks X to close a tab.
|
| + * On portrait, positive direction (x) is right hand side.
|
| + * On landscape, positive direction (y) is towards bottom.
|
| + * @return True, if default discard direction is positive.
|
| + */
|
| + protected abstract boolean isDefaultDiscardDirectionPositive();
|
| +
|
| + /**
|
| + * Responsible for generating the animations that shows a new tab being opened.
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the
|
| + * tabs that will be affected by the TabSwitcherAnimation.
|
| + * @param focusIndex The focused index. In this case, this is the index of
|
| + * the tab that was just created.
|
| + * @param discardRange The maximum value the discard amount.
|
| + * @return The TabSwitcherAnimation instance that will tween the
|
| + * tabs to create the appropriate animation.
|
| + */
|
| + // TODO(dtrainor): Remove this after confirming nothing uses this.
|
| + protected ChromeAnimation<?> createNewTabOpenedAnimatorSet(
|
| + StackTab[] tabs, int focusIndex, float discardRange) {
|
| + if (focusIndex < 0 || focusIndex >= tabs.length) return null;
|
| + ChromeAnimation<Animatable<?>> set = new ChromeAnimation<Animatable<?>>();
|
| +
|
| + StackTab tab = tabs[focusIndex];
|
| + tab.getLayoutTab().setVisible(false);
|
| + tab.setXInStackInfluence(0.0f);
|
| + tab.setYInStackInfluence(0.0f);
|
| + tab.setDiscardFromClick(true);
|
| + tab.setDiscardOriginX(tab.getLayoutTab().getOriginalContentWidth());
|
| + tab.setDiscardOriginY(tab.getLayoutTab().getOriginalContentHeight() / 2.f);
|
| + tab.getLayoutTab().setAlpha(0.0f);
|
| + tab.getLayoutTab().setBorderAlpha(0.0f);
|
| + addAnimation(set, tab, DISCARD_AMOUNT, getTabCreationDirection() * discardRange, 0.0f,
|
| + TAB_OPENED_ANIMATION_DURATION, 0, false,
|
| + ChromeAnimation.getAccelerateInterpolator());
|
| + return set;
|
| + }
|
| +
|
| + /**
|
| + * Responsible for generating the animations that flattens tabs when a pinch begins.
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the tabs that will
|
| + * be affected by the animations.
|
| + * @return The TabSwitcherAnimation instance that will tween the tabs to
|
| + * create the appropriate animation.
|
| + */
|
| + protected ChromeAnimation<?> createStartPinchAnimatorSet(StackTab[] tabs) {
|
| + ChromeAnimation<Animatable<?>> set = new ChromeAnimation<Animatable<?>>();
|
| +
|
| + for (int i = 0; i < tabs.length; ++i) {
|
| + addTiltScrollAnimation(
|
| + set, tabs[i].getLayoutTab(), 0, START_PINCH_ANIMATION_DURATION, 0);
|
| + }
|
| +
|
| + return set;
|
| + }
|
| +
|
| + /**
|
| + * Responsible for generating the animations that make all the tabs do a full roll.
|
| + *
|
| + * @param tabs The tabs that make up the stack. These are the tabs that will be affected by the
|
| + * animations.
|
| + * @return The TabSwitcherAnimation instance that will tween the tabs to create the
|
| + * appropriate animation.
|
| + */
|
| + protected ChromeAnimation<?> createFullRollAnimatorSet(StackTab[] tabs) {
|
| + ChromeAnimation<Animatable<?>> set = new ChromeAnimation<Animatable<?>>();
|
| +
|
| + for (int i = 0; i < tabs.length; ++i) {
|
| + LayoutTab layoutTab = tabs[i].getLayoutTab();
|
| + // Set the pivot
|
| + layoutTab.setTiltX(layoutTab.getTiltX(), layoutTab.getScaledContentHeight() / 2.0f);
|
| + layoutTab.setTiltY(layoutTab.getTiltY(), layoutTab.getScaledContentWidth() / 2.0f);
|
| + // Create the angle animation
|
| + addTiltScrollAnimation(set, layoutTab, -360.0f, FULL_ROLL_ANIMATION_DURATION, 0);
|
| + }
|
| +
|
| + return set;
|
| + }
|
| +
|
| + /**
|
| + * @return The offset for the toolbar to line the top up with the opaque component of the
|
| + * border.
|
| + */
|
| + protected float getToolbarOffsetToLineUpWithBorder() {
|
| + final float toolbarHeight = mHeight - mHeightMinusTopControls;
|
| + return toolbarHeight - mBorderTopOpaqueHeight;
|
| + }
|
| +}
|
|
|