Skip to content

Commit

Permalink
[TabStripRedesign] Add edit mode tab group containers
Browse files Browse the repository at this point in the history
Add edit mode tab group containers.
-Show slightly transparent containers for tabs in hovered tab group.
-Suppress edit mode background tab dimming when TSR enabled.
-Account for the close button's built-in padding to correctly place it
 in the tab container.
-Adjust overlap width to make the effective distance between tab
 containers 4dp as per spec. Also fix tests accordingly.
-Adjust divider offset to re-center with new tab container & close
 button positioning.

Folio: https://drive.google.com/file/d/1bvBP11xrgkgJl-DkF93PtunGq2gc3Bc2/view?usp=share_link
Detached: https://drive.google.com/file/d/179rj2eyegU_teESU5WKXL52t4pOM5xNx/view?usp=share_link

Bug: 1403030
Change-Id: Ib0881c953d990dae4e2273a6afef4305d0352a73
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4177778
Reviewed-by: Sirisha Kavuluru <skavuluru@google.com>
Commit-Queue: Neil Coronado <nemco@google.com>
Cr-Commit-Position: refs/heads/main@{#1095924}
  • Loading branch information
Neil Coronado authored and Chromium LUCI CQ committed Jan 24, 2023
1 parent a92caac commit 1a6941c
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,68 @@ public static int getTabStripDetachedTabColor(Context context, boolean isIncogni
}
}

/**
* Returns the value that corresponds to Surface-0 based on incognito status.
*
* @param context {@link Context} used to retrieve color.
* @param isIncognito Whether the color is used for incognito mode.
* @return The value that corresponds to Surface-0.
*/
private static int getSurfaceColorElev0(Context context, boolean isIncognito) {
if (isIncognito) {
return context.getColor(org.chromium.chrome.R.color.default_bg_color_dark);
}

return ChromeColors.getSurfaceColor(
context, org.chromium.chrome.R.dimen.default_elevation_0);
}

/**
* Returns the value that corresponds to Surface-5 based on incognito status.
*
* @param context {@link Context} used to retrieve color.
* @param isIncognito Whether the color is used for incognito mode.
* @return The value that corresponds to Surface-5.
*/
private static int getSurfaceColorElev5(Context context, boolean isIncognito) {
if (isIncognito) {
return context.getColor(
org.chromium.chrome.R.color.default_bg_color_dark_elev_5_baseline);
}

return ChromeColors.getSurfaceColor(
context, org.chromium.chrome.R.dimen.default_elevation_5);
}

/**
* Returns the color for the tab container based on experiment arm, incognito mode, and
* foreground status.
*
* @param context {@link Context} used to retrieve color.
* @param isIncognito Whether the color is used for incognito mode.
* @param foreground Whether the tab is in the foreground.
* @return The color for the tab container.
*/
public static int getTabStripContainerColor(
Context context, boolean isIncognito, boolean foreground) {
if (foreground) {
if (TabUiFeatureUtilities.isTabStripFolioEnabled()) {
return ChromeColors.getDefaultThemeColor(context, isIncognito);
} else if (TabUiFeatureUtilities.isTabStripDetachedEnabled()) {
return getTabStripDetachedTabColor(context, isIncognito);
}
} else {
if (TabUiFeatureUtilities.isTabStripFolioEnabled()) {
return getSurfaceColorElev0(context, isIncognito);
} else if (TabUiFeatureUtilities.isTabStripDetachedEnabled()) {
return getSurfaceColorElev5(context, isIncognito);
}
}

// Should be unreachable as TSR should never be enabled without the folio or detached arm.
return Color.TRANSPARENT;
}

/**
* Returns the color used for tab grid dialog background based on the incognito mode.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public Float get(StripLayoutHelper object) {
// Visibility Constants
private static final float TAB_STACK_WIDTH_DP = 4.f;
private static final float TAB_OVERLAP_WIDTH_DP = 24.f;
private static final float TAB_OVERLAP_WIDTH_LARGE_DP = 28.f;
private static final float TAB_WIDTH_SMALL = 108.f;
private static final float TAB_WIDTH_MEDIUM = 156.f;
private static final float MAX_TAB_WIDTH_DP = 265.f;
Expand All @@ -148,6 +149,9 @@ public Float get(StripLayoutHelper object) {
private static final float NEW_TAB_BUTTON_DESIRED_TOUCH_TARGET_SIZE = 48.f;
private static final float NEW_TAB_BUTTON_DEFAULT_PRESSED_OPACITY = 0.2f;
private static final float NEW_TAB_BUTTON_DARK_DETACHED_OPACITY = 0.15f;
static final float TAB_OPACITY_HIDDEN = 0.f;
static final float TAB_OPACITY_VISIBLE_BACKGROUND = 0.55f;
static final float TAB_OPACITY_VISIBLE_FOREGROUND = 1.f;
static final float BACKGROUND_TAB_BRIGHTNESS_DEFAULT = 1.f;
static final float BACKGROUND_TAB_BRIGHTNESS_DIMMED = 0.65f;
static final float DIVIDER_HIDDEN_OPACITY = 0.f;
Expand Down Expand Up @@ -253,7 +257,9 @@ public Float get(StripLayoutHelper object) {
*/
public StripLayoutHelper(Context context, LayoutUpdateHost updateHost,
LayoutRenderHost renderHost, boolean incognito, CompositorButton modelSelectorButton) {
mTabOverlapWidth = TAB_OVERLAP_WIDTH_DP;
mTabOverlapWidth = ChromeFeatureList.sTabStripRedesign.isEnabled()
? TAB_OVERLAP_WIDTH_LARGE_DP
: TAB_OVERLAP_WIDTH_DP;
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
if (TabUiFeatureUtilities.isTabStripFolioEnabled()) {
mNewTabButtonWidth = NEW_TAB_BUTTON_BACKGROUND_WIDTH_DP_FOLIO;
Expand Down Expand Up @@ -702,6 +708,11 @@ public void tabSelected(long time, int id, int prevId, boolean skipAutoScroll) {
setAccessibilityDescription(stripTab, getTabById(id));
setAccessibilityDescription(findTabById(prevId), getTabById(prevId));
}

StripLayoutTab selectedTab = findTabById(id);
StripLayoutTab prevTab = findTabById(prevId);
selectedTab.setContainerOpacity(TAB_OPACITY_VISIBLE_FOREGROUND);
if (prevTab != null) prevTab.setContainerOpacity(TAB_OPACITY_HIDDEN);
}

/**
Expand Down Expand Up @@ -873,8 +884,11 @@ private void updateDividers() {
for (int i = 1; i < mStripTabs.length; i++) {
final StripLayoutTab prevTab = mStripTabs[i - 1];
final StripLayoutTab currTab = mStripTabs[i];
if (prevTab.getId() == selectedTabId || currTab.getId() == selectedTabId) {
// Dividers adjacent to the selected tab are hidden.
if (prevTab.getId() == selectedTabId || currTab.getId() == selectedTabId
|| currTab.getContainerOpacity() > TAB_OPACITY_HIDDEN) {
// Dividers adjacent to selected tab are hidden. Additionally, when tab containers
// are visible for grouped tabs in edit mode, tab dividers are unneeded and
// therefore hidden.
currTab.setDividerOpacity(DIVIDER_HIDDEN_OPACITY);
} else {
// All other dividers are visible.
Expand Down Expand Up @@ -1496,6 +1510,9 @@ private StripLayoutTab createStripTab(int id) {
StripLayoutTab tab = new StripLayoutTab(
mContext, id, this, mTabLoadTrackerHost, mRenderHost, mUpdateHost, mIncognito);
tab.setHeight(mHeight);
if (id == mModel.getTabAt(mModel.index()).getId()) {
tab.setContainerOpacity(TAB_OPACITY_VISIBLE_FOREGROUND);
}
pushStackerPropertiesToTab(tab);
return tab;
}
Expand Down Expand Up @@ -1836,6 +1853,12 @@ private void updateFolioTabAttachState(
float endValue =
attached ? FOLIO_ATTACHED_BOTTOM_MARGIN_DP : FOLIO_DETACHED_BOTTOM_MARGIN_DP;

if (animationList == null) {
tab.setBottomMargin(endValue);
tab.setFolioAttached(attached);
return;
}

ArrayList<Animator> attachAnimationList = new ArrayList<>();
CompositorAnimator dropAnimation = CompositorAnimator.ofFloatProperty(
mUpdateHost.getAnimationHandler(), tab, StripLayoutTab.BOTTOM_MARGIN, startValue,
Expand All @@ -1855,12 +1878,7 @@ public void onAnimationEnd(Animator animation) {

AnimatorSet set = new AnimatorSet();
set.playSequentially(attachAnimationList);

if (animationList == null) {
set.end();
} else {
animationList.add(set);
}
animationList.add(set);
}

@VisibleForTesting
Expand Down Expand Up @@ -1911,7 +1929,9 @@ private void startReorderMode(long time, float currentX, float startX) {
mModel, TabModelUtils.getTabIndexById(mModel, mInteractingTab.getId()), false);

// 5. Dim the background tabs and fade-out the new tab & model selector buttons.
setBackgroundTabsDimmed(true);
if (!ChromeFeatureList.sTabStripRedesign.isEnabled()) {
setBackgroundTabsDimmed(true);
}
setCompositorButtonsVisible(false);

// 6. Fast expand to make sure this tab is visible. If tabs are not cascaded, the selected
Expand All @@ -1924,7 +1944,11 @@ private void startReorderMode(long time, float currentX, float startX) {
} else if (TabUiFeatureUtilities.isTabletTabGroupsEnabled(mContext)) {
Tab tab = getTabById(mInteractingTab.getId());
computeAndUpdateTabGroupMargins(true, animationList);
setTabGroupDimmed(mTabGroupModelFilter.getRootId(tab), false);
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
setTabGroupContainersVisible(mTabGroupModelFilter.getRootId(tab), true);
} else {
setTabGroupDimmed(mTabGroupModelFilter.getRootId(tab), false);
}
performHapticFeedback(tab);
}

Expand Down Expand Up @@ -1959,8 +1983,12 @@ private void stopReorderMode() {
mInteractingTab.setOffsetX(0f);
}

// 3. Un-dim the background tabs and fade-in the new tab & model selector buttons.
setBackgroundTabsDimmed(false);
// 3. Reset the background tabs and fade-in the new tab & model selector buttons.
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
setBackgroundTabContainersVisible(false);
} else {
setBackgroundTabsDimmed(false);
}
setCompositorButtonsVisible(true);

// 4. Clear any tab group margins if they are enabled.
Expand Down Expand Up @@ -2167,6 +2195,34 @@ private void setTabGroupDimmed(int groupId, boolean dimmed) {
}
}

private void setTabContainerVisible(StripLayoutTab tab, boolean visible) {
if (tab != mInteractingTab) {
float opacity = visible ? TAB_OPACITY_VISIBLE_BACKGROUND : TAB_OPACITY_HIDDEN;
tab.setContainerOpacity(opacity);

if (TabUiFeatureUtilities.isTabStripFolioEnabled()) {
updateFolioTabAttachState(tab, !visible, null);
}
}
}

private void setBackgroundTabContainersVisible(boolean visible) {
for (int i = 0; i < mStripTabs.length; i++) {
final StripLayoutTab tab = mStripTabs[i];
setTabContainerVisible(tab, visible);
}
}

private void setTabGroupContainersVisible(int groupId, boolean visible) {
for (int i = 0; i < mStripTabs.length; i++) {
final StripLayoutTab tab = mStripTabs[i];

if (mTabGroupModelFilter.getRootId(getTabById(tab.getId())) == groupId) {
setTabContainerVisible(tab, visible);
}
}
}

/**
* This method checks whether or not interacting tab has met the conditions to be moved out of
* its tab group. It moves tab out of group if so and returns the new index for the interacting
Expand All @@ -2183,7 +2239,12 @@ private int maybeMoveOutOfGroup(float offset, int curIndex, boolean towardEnd) {
if (Math.abs(offset) > mTabMarginWidth * REORDER_OVERLAP_SWITCH_PERCENTAGE) {
final int tabId = mInteractingTab.getId();

setTabGroupDimmed(mTabGroupModelFilter.getRootId(getTabById(tabId)), true);
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
setTabGroupContainersVisible(
mTabGroupModelFilter.getRootId(getTabById(tabId)), false);
} else {
setTabGroupDimmed(mTabGroupModelFilter.getRootId(getTabById(tabId)), true);
}
mTabGroupModelFilter.moveTabOutOfGroupInDirection(tabId, towardEnd);
RecordUserAction.record("MobileToolbarReorderTab.TabRemovedFromGroup");
return curIndex;
Expand Down Expand Up @@ -2253,7 +2314,11 @@ private int updateHoveringOverGroup(float offset, int curIndex, boolean towardEn
// 1.b. Set tab group dim as necessary.
int groupId = mTabGroupModelFilter.getRootId(
getTabById(mStripTabs[curIndex + (towardEnd ? 1 : -1)].getId()));
setTabGroupDimmed(groupId, !mHoveringOverGroup);
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
setTabGroupContainersVisible(groupId, mHoveringOverGroup);
} else {
setTabGroupDimmed(groupId, !mHoveringOverGroup);
}
}

// 2. If we are hovering, attempt to merge to the hovered group.
Expand Down Expand Up @@ -2285,7 +2350,11 @@ private int maybeMovePastGroup(float offset, int curIndex, boolean towardEnd) {

// If past threshold, un-dim hovered group and trigger reorder.
if (Math.abs(offset) > threshold) {
setTabGroupDimmed(groupId, true);
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
setTabGroupContainersVisible(groupId, false);
} else {
setTabGroupDimmed(groupId, true);
}

int destIndex = towardEnd ? curIndex + 1 + numTabsToSkip : curIndex - numTabsToSkip;
return destIndex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ public Float get(StripLayoutTab object) {
// Animation/Timer Constants
private static final int ANIM_TAB_CLOSE_BUTTON_FADE_MS = 150;

// Close button width
// Close Button Constants
// Close button padding value comes from the built-in padding in the source png.
private static final int CLOSE_BUTTON_PADDING_DP = 7;
private static final int CLOSE_BUTTON_WIDTH_DP = 36;
private static final int CLOSE_BUTTON_WIDTH_SCROLLING_STRIP_DP = 48;

Expand All @@ -188,7 +190,7 @@ public Float get(StripLayoutTab object) {

// Divider Constants
// TODO(crbug.com/1373632): Temp value until the 9-patches are updated.
private static final int DIVIDER_OFFSET_X = 9;
private static final int DIVIDER_OFFSET_X = 13;
@VisibleForTesting
static final float DIVIDER_FOLIO_LIGHT_OPACITY = 0.2f;

Expand All @@ -207,6 +209,7 @@ public Float get(StripLayoutTab object) {
private boolean mFolioAttached = true;
private final boolean mIncognito;
private float mBottomMargin;
private float mContainerOpacity;
private float mContentOffsetX;
private float mDividerOpacity;
private float mVisiblePercentage = 1.f;
Expand Down Expand Up @@ -379,15 +382,10 @@ public int getDividerResourceId() {
* @return The tint color resource that represents the tab background.
*/
public int getTint(boolean foreground) {
// TODO(https://crbug.com/1408276): Avoid calculating every time. Instead, store the tab's
// color and only re-determine when the color could have changed (i.e. on selection).
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
// Inactive tabs have no container in TSR. Return arbitrary color to avoid calculation.
if (!foreground) return Color.TRANSPARENT;

if (TabUiFeatureUtilities.isTabStripFolioEnabled()) {
return ChromeColors.getDefaultThemeColor(mContext, mIncognito);
} else if (TabUiFeatureUtilities.isTabStripDetachedEnabled()) {
return TabUiThemeProvider.getTabStripDetachedTabColor(mContext, mIncognito);
}
return TabUiThemeProvider.getTabStripContainerColor(mContext, mIncognito, foreground);
}

if (foreground) {
Expand Down Expand Up @@ -575,18 +573,21 @@ public float getBrightness() {
}

/**
* @param foreground Whether or not this tab is a foreground tab.
* @return The fraction (from 0.f to 1.f) of how opaque the tab should be.
* @param opacity The fraction (from 0.f to 1.f) of how opaque the tab container should be.
*/
public void setContainerOpacity(float opacity) {
mContainerOpacity = opacity;
}

/**
* @return The fraction (from 0.f to 1.f) of how opaque the tab container should be.
*/
public float getOpacity(boolean foreground) {
public float getContainerOpacity() {
if (ChromeFeatureList.sTabStripRedesign.isEnabled()) {
if (foreground) {
return 1.0f;
} else {
return 0.0f;
}
return mContainerOpacity;
} else {
return 1.f;
}
return 1.0f;
}

/**
Expand Down Expand Up @@ -883,6 +884,10 @@ private RectF getCloseRect() {
return mClosePlacement;
}

public int getCloseButtonPadding() {
return CLOSE_BUTTON_PADDING_DP;
}

// TODO(dtrainor): Don't animate this if we're selecting or deselecting this tab.
private void checkCloseButtonVisibility(boolean animate) {
boolean shouldShow =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,10 @@ private void pushStripTabs(StripLayoutHelperManager layoutHelper,
st.getDrawX() * mDpToPx, st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx,
st.getHeight() * mDpToPx, st.getContentOffsetX() * mDpToPx,
st.getContentOffsetY() * mDpToPx, st.getDividerOffsetX() * mDpToPx,
st.getBottomMargin() * mDpToPx, st.getCloseButton().getOpacity(),
st.getDividerOpacity(), st.isLoading(), st.getLoadingSpinnerRotation(),
st.getBrightness(), st.getOpacity(isSelected), layerTitleCache,
resourceManager);
st.getBottomMargin() * mDpToPx, st.getCloseButtonPadding() * mDpToPx,
st.getCloseButton().getOpacity(), st.getDividerOpacity(), st.isLoading(),
st.getLoadingSpinnerRotation(), st.getBrightness(), st.getContainerOpacity(),
layerTitleCache, resourceManager);
}
}

Expand Down Expand Up @@ -255,8 +255,8 @@ void putStripTabLayer(long nativeTabStripSceneLayer, TabStripSceneLayer caller,
int handleOutlineTint, boolean foreground, boolean closePressed, float toolbarWidth,
float x, float y, float width, float height, float contentOffsetX,
float contentOffsetY, float dividerOffsetX, float bottomOffsetY,
float closeButtonAlpha, float dividerAlpha, boolean isLoading,
float spinnerRotation, float brightness, float opacity,
float closeButtonPadding, float closeButtonAlpha, float dividerAlpha,
boolean isLoading, float spinnerRotation, float brightness, float opacity,
LayerTitleCache layerTitleCache, ResourceManager resourceManager);
void setContentTree(
long nativeTabStripSceneLayer, TabStripSceneLayer caller, SceneLayer contentTree);
Expand Down

0 comments on commit 1a6941c

Please sign in to comment.