Commit 648781b9 authored by Wei-Yin Chen (陳威尹)'s avatar Wei-Yin Chen (陳威尹) Committed by Commit Bot

Make transition animation in Grid Tab Switcher closer to spec (2)

Updates in Tab-to-Grid transition animation:
- Do not show the selected blue border in the grid when the tab resizes
- Fade in the selected blue border along with the GTS final fading-in

Bug: 971522
Change-Id: If788855ce4659226900759517cf7f8e9ab536e9e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1648835
Commit-Queue: Wei-Yin Chen (陳威尹) <wychen@chromium.org>
Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#667204}
parent c6c1ad32
......@@ -27,6 +27,10 @@ public interface GridTabSwitcher {
*/
interface GridVisibilityObserver extends OverviewModeBehavior.OverviewModeObserver {}
/**
* @return GridController implementation that can be used for controlling
* grid visibility changes.
*/
GridController getGridController();
/**
......
......@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.tasks.tab_management;
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.compositor.CompositorViewHolder;
......@@ -19,7 +20,6 @@ import org.chromium.chrome.browser.lifecycle.Destroyable;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.browser.tabmodel.TabList;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.util.FeatureUtilities;
import org.chromium.ui.modelutil.PropertyModel;
......@@ -97,10 +97,7 @@ public class GridTabSwitcherCoordinator
mLifecycleDispatcher.register(this);
}
/**
* @return GridController implementation that will can be used for controlling
* grid visibility changes.
*/
// GridTabSwitcher implementation.
@Override
public GridController getGridController() {
return mMediator;
......@@ -108,8 +105,9 @@ public class GridTabSwitcherCoordinator
@Override
public boolean prepareOverview() {
boolean quick = mMediator.prepareOverview();
mTabGridCoordinator.prepareOverview();
return mMediator.prepareOverview();
return quick;
}
@Override
......@@ -135,12 +133,9 @@ public class GridTabSwitcherCoordinator
return mTabGridCoordinator.getLastDirtyTimeForTesting();
}
/**
* Reset the tab grid with the given {@link TabModel}. Can be null.
* @param tabList The current {@link TabList} to show the tabs for in the grid.
*/
// ResetHandler implementation.
@Override
public boolean resetWithTabList(TabList tabList) {
public boolean resetWithTabList(@Nullable TabList tabList, boolean quickMode) {
List<Tab> tabs = null;
if (tabList != null) {
tabs = new ArrayList<>();
......@@ -148,7 +143,7 @@ public class GridTabSwitcherCoordinator
tabs.add(tabList.getTabAt(i));
}
}
return mTabGridCoordinator.resetWithListOfTabs(tabs);
return mTabGridCoordinator.resetWithListOfTabs(tabs, quickMode);
}
@Override
......@@ -156,6 +151,7 @@ public class GridTabSwitcherCoordinator
mTabGridCoordinator.softCleanup();
}
// ResetHandler implementation.
@Override
public void destroy() {
mTabGridCoordinator.destroy();
......
......@@ -108,9 +108,12 @@ class GridTabSwitcherMediator
*/
interface ResetHandler {
/**
* Reset the tab grid with the given {@link TabList}, which can be null.
* @param tabList The {@link TabList} to show the tabs for in the grid.
* @param quickMode Whether to skip capturing the selected live tab for the thumbnail.
* @return Whether the {@link TabListRecyclerView} can be shown quickly.
*/
boolean resetWithTabList(TabList tabList);
boolean resetWithTabList(@Nullable TabList tabList, boolean quickMode);
/**
* Release the thumbnail {@link Bitmap} but keep the {@link TabGridViewHolder}.
......@@ -143,7 +146,7 @@ class GridTabSwitcherMediator
TabList currentTabModelFilter =
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter();
mResetHandler.resetWithTabList(currentTabModelFilter);
mResetHandler.resetWithTabList(currentTabModelFilter, false);
mContainerViewModel.set(IS_INCOGNITO, currentTabModelFilter.isIncognito());
}
};
......@@ -195,7 +198,7 @@ class GridTabSwitcherMediator
mTabGridDialogResetHandler = tabGridDialogResetHandler;
mSoftClearTabListRunnable = mResetHandler::softCleanup;
mClearTabListRunnable = () -> mResetHandler.resetWithTabList(null);
mClearTabListRunnable = () -> mResetHandler.resetWithTabList(null, false);
mHandler = new Handler();
}
......@@ -263,7 +266,7 @@ class GridTabSwitcherMediator
mHandler.removeCallbacks(mSoftClearTabListRunnable);
mHandler.removeCallbacks(mClearTabListRunnable);
boolean quick = mResetHandler.resetWithTabList(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter());
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), false);
int initialPosition = Math.max(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter().index()
- INITIAL_SCROLL_INDEX_OFFSET,
......@@ -274,6 +277,8 @@ class GridTabSwitcherMediator
@Override
public void showOverview(boolean animate) {
mResetHandler.resetWithTabList(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), true);
if (!animate) mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, false);
setVisibility(true);
mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, true);
......
......@@ -126,7 +126,7 @@ public class TabGridDialogMediator {
private void updateGridTabSwitcher() {
if (!mModel.get(TabGridSheetProperties.IS_DIALOG_VISIBLE)) return;
mGridTabSwitcherResetHandler.resetWithTabList(
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter());
mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), false);
}
private void updateDialog() {
......
......@@ -185,15 +185,18 @@ public class TabListCoordinator implements Destroyable {
}
/**
* Reset the tab grid with the given List of Tabs. Can be null.
* @param tabs List of Tabs to show for in the UI.
* @see TabListMediator#resetWithListOfTabs(List, boolean)
*/
public boolean resetWithListOfTabs(@Nullable List<Tab> tabs) {
boolean resetWithListOfTabs(@Nullable List<Tab> tabs, boolean quickMode) {
if (mMode == TabListMode.STRIP && tabs != null && tabs.size() > 1) {
TabGroupUtils.maybeShowIPH(
FeatureConstants.TAB_GROUPS_TAP_TO_SEE_ANOTHER_TAB_FEATURE, mRecyclerView);
}
return mMediator.resetWithListOfTabs(tabs);
return mMediator.resetWithListOfTabs(tabs, quickMode);
}
boolean resetWithListOfTabs(@Nullable List<Tab> tabs) {
return resetWithListOfTabs(tabs, false);
}
void softCleanup() {
......@@ -202,6 +205,7 @@ public class TabListCoordinator implements Destroyable {
void prepareOverview() {
mRecyclerView.prepareOverview();
mMediator.prepareOverview();
}
void postHiding() {
......
......@@ -535,6 +535,21 @@ class TabListMediator {
return position != TabModel.INVALID_TAB_INDEX && position < mModel.size();
}
/**
* Hide the blue border for selected tab for the Tab-to-Grid resizing stage.
* The selected border should re-appear in the final fading-in stage.
*/
void prepareOverview() {
int count = 0;
for (int i = 0; i < mModel.size(); i++) {
if (mModel.get(i).get(TabProperties.IS_SELECTED)) count++;
mModel.get(i).set(TabProperties.IS_SELECTED, false);
}
assert (count == 1)
: "There should be exactly one selected tab when calling "
+ "TabListMediator.prepareOverview()";
}
private boolean areTabsUnchanged(@Nullable List<Tab> tabs) {
if (tabs == null) {
return mModel.size() == 0;
......@@ -549,9 +564,10 @@ class TabListMediator {
/**
* Initialize the component with a list of tabs to show in a grid.
* @param tabs The list of tabs to be shown.
* @param quickMode Whether to skip capturing the selected live tab for the thumbnail.
* @return Whether the {@link TabListRecyclerView} can be shown quickly.
*/
public boolean resetWithListOfTabs(@Nullable List<Tab> tabs) {
boolean resetWithListOfTabs(@Nullable List<Tab> tabs, boolean quickMode) {
if (areTabsUnchanged(tabs)) {
if (tabs == null) return true;
......@@ -563,7 +579,7 @@ class TabListMediator {
boolean isSelected = mTabModelSelector.getCurrentTab() == tab;
mModel.get(i).set(TabProperties.IS_SELECTED, isSelected);
if (mThumbnailProvider != null && isSelected) {
if (mThumbnailProvider != null && isSelected && !quickMode) {
ThumbnailFetcher callback = new ThumbnailFetcher(mThumbnailProvider, tab, true);
mModel.get(i).set(TabProperties.THUMBNAIL_FETCHER, callback);
}
......
......@@ -286,7 +286,7 @@ public class GridTabSwitcherMediatorUnitTest {
mMediator.setCleanupDelayForTesting(0);
mMediator.postHiding();
verify(mResetHandler).softCleanup();
verify(mResetHandler).resetWithTabList(eq(null));
verify(mResetHandler).resetWithTabList(eq(null), eq(false));
}
@Test
......@@ -295,7 +295,7 @@ public class GridTabSwitcherMediatorUnitTest {
doReturn(true).when(mTabModelFilter).isIncognito();
mTabModelSelectorObserverCaptor.getValue().onTabModelSelected(mTabModel, null);
verify(mResetHandler).resetWithTabList(eq(mTabModelFilter));
verify(mResetHandler).resetWithTabList(eq(mTabModelFilter), eq(false));
assertThat(mModel.get(TabListContainerProperties.IS_INCOGNITO), equalTo(true));
// Switching TabModels by itself shouldn't cause visibility changes.
......
......@@ -578,7 +578,7 @@ public class TabListMediatorUnitTest {
for (int i = 0; i < mTabModel.getCount(); i++) {
tabs.add(mTabModel.getTabAt(i));
}
mMediator.resetWithListOfTabs(tabs);
mMediator.resetWithListOfTabs(tabs, false);
for (Callback<Drawable> callback : mCallbackCaptor.getAllValues()) {
callback.onResult(new ColorDrawable(Color.RED));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment