Skip to content

Commit

Permalink
[TabStripRedesign] Add missing start / end dividers for tab strip
Browse files Browse the repository at this point in the history
Demo: https://drive.google.com/file/d/1euYlZYdZifZr40npIckDmf53cV1rl5Gr/view?usp=share_link
Spec: https://docs.google.com/presentation/d/1VxlgkrY0ef5bVJiE1EC3qK8qkLCh5AmZHWRhaV0xB4Y/edit?resourcekey=0-7c1vUSKo4bZhr4gn178ALw#slide=id.g180ed310390_0_4

Bug: 1412231
Change-Id: I8f32508af79615cf6828ce1675854d62761fe1b1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4214878
Reviewed-by: Neil Coronado <nemco@google.com>
Commit-Queue: Sirisha Kavuluru <skavuluru@google.com>
Cr-Commit-Position: refs/heads/main@{#1100203}
  • Loading branch information
Sirisha Kavuluru authored and Chromium LUCI CQ committed Feb 2, 2023
1 parent ad4a4bb commit d4c5b7d
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,6 @@ public Float get(StripLayoutHelper object) {
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;
static final float DIVIDER_DEFAULT_OPACITY = 1.f;
static final float FADE_FULL_OPACITY_THRESHOLD_DP = 24.f;

private static final int MESSAGE_RESIZE = 1;
Expand Down Expand Up @@ -884,8 +882,14 @@ private void updateForegroundTabContainersAndDividers() {
int selectedTabId = mStripTabs[index].getId();

// Divider is never shown for the first tab.
mStripTabs[0].setDividerOpacity(DIVIDER_HIDDEN_OPACITY);
mStripTabs[0].setStartDividerVisible(false);
setForegroundTabContainerVisible(mStripTabs[0], selectedTabId);
// End divider for first tab is only shown in reorder mode when tab has trailing margin and
// container is not visible.
boolean endDividerVisible = mInReorderMode
&& mStripTabs[0].getContainerOpacity() == TAB_OPACITY_HIDDEN
&& mStripTabs[0].getTrailingMargin() > 0;
mStripTabs[0].setEndDividerVisible(endDividerVisible);

for (int i = 1; i < mStripTabs.length; i++) {
final StripLayoutTab prevTab = mStripTabs[i - 1];
Expand All @@ -894,17 +898,30 @@ private void updateForegroundTabContainersAndDividers() {
// Set container opacity.
setForegroundTabContainerVisible(currTab, selectedTabId);

// Set divider opacity.
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.
currTab.setDividerOpacity(DIVIDER_DEFAULT_OPACITY);
}
/**
* Start divider should be visible when:
* 1. In reorder mode and currTab container is hidden
* 2. Not in reorder mode and prevTab is not selected and currTab is not selected
*/
boolean startDividerVisible =
(mInReorderMode && currTab.getContainerOpacity() == TAB_OPACITY_HIDDEN)
|| (!mInReorderMode && prevTab.getId() != selectedTabId
&& currTab.getId() != selectedTabId);
currTab.setStartDividerVisible(startDividerVisible);

/**
* End divider should be applied when:
* 1. In reorder mode and currTab container is hidden and
* (a) currTab's trailing margin > 0 (ie last tab in group) OR
* (b) currTab is last tab in strip (last tab does not have trailing margin)
* 2. Not in reorder mode and currTab is last tab on strip and is not selected
*/
endDividerVisible =
(mInReorderMode && currTab.getContainerOpacity() == TAB_OPACITY_HIDDEN
&& (currTab.getTrailingMargin() > 0 || i == (mStripTabs.length - 1)))
|| (!mInReorderMode && i == (mStripTabs.length - 1)
&& currTab.getId() != selectedTabId);
currTab.setEndDividerVisible(endDividerVisible);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ public Float get(StripLayoutTab object) {
private static final float DETACHED_CONTENT_OFFSET_Y = 10.f;

// Divider Constants
// TODO(crbug.com/1373632): Temp value until the 9-patches are updated.
private static final int DIVIDER_OFFSET_X = 13;
@VisibleForTesting
static final float DIVIDER_FOLIO_LIGHT_OPACITY = 0.2f;
Expand All @@ -207,11 +206,12 @@ public Float get(StripLayoutTab object) {
private boolean mIsDying;
private boolean mCanShowCloseButton = true;
private boolean mFolioAttached = true;
private boolean mStartDividerVisible;
private boolean mEndDividerVisible;
private final boolean mIncognito;
private float mBottomMargin;
private float mContainerOpacity;
private float mContentOffsetX;
private float mDividerOpacity;
private float mVisiblePercentage = 1.f;
private String mAccessibilityDescription;

Expand Down Expand Up @@ -459,17 +459,31 @@ public int getOutlineTint(boolean foreground) {
}

/**
* @param dividerOpacity The new opacity for the tab divider.
* @param visible Visibility of tab's start divider.
*/
public void setDividerOpacity(float dividerOpacity) {
mDividerOpacity = dividerOpacity;
public void setStartDividerVisible(boolean visible) {
mStartDividerVisible = visible;
}

/**
* @return The opacity of the tab divider.
* @return Visibility of tab's start divider.
*/
public float getDividerOpacity() {
return mDividerOpacity;
public boolean isStartDividerVisible() {
return mStartDividerVisible;
}

/**
* @param visible Visibility of end divider.
*/
public void setEndDividerVisible(boolean visible) {
mEndDividerVisible = visible;
}

/**
* @return Visibility of tab's end divider.
*/
public boolean isEndDividerVisible() {
return mEndDividerVisible;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,9 @@ private void pushStripTabs(StripLayoutHelperManager layoutHelper,
st.getHeight() * mDpToPx, st.getContentOffsetX() * mDpToPx,
st.getContentOffsetY() * mDpToPx, st.getDividerOffsetX() * mDpToPx,
st.getBottomMargin() * mDpToPx, st.getCloseButtonPadding() * mDpToPx,
st.getCloseButton().getOpacity(), st.getDividerOpacity(), st.isLoading(),
st.getLoadingSpinnerRotation(), st.getBrightness(), st.getContainerOpacity(),
layerTitleCache, resourceManager);
st.getCloseButton().getOpacity(), st.isStartDividerVisible(),
st.isEndDividerVisible(), st.isLoading(), st.getLoadingSpinnerRotation(),
st.getBrightness(), st.getContainerOpacity(), layerTitleCache, resourceManager);
}
}

Expand Down Expand Up @@ -255,9 +255,10 @@ 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 closeButtonPadding, float closeButtonAlpha, float dividerAlpha,
boolean isLoading, float spinnerRotation, float brightness, float opacity,
LayerTitleCache layerTitleCache, ResourceManager resourceManager);
float closeButtonPadding, float closeButtonAlpha, boolean isStartDividerVisible,
boolean isEndDividerVisible, boolean isLoading, float spinnerRotation,
float brightness, float opacity, LayerTitleCache layerTitleCache,
ResourceManager resourceManager);
void setContentTree(
long nativeTabStripSceneLayer, TabStripSceneLayer caller, SceneLayer contentTree);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,21 +487,53 @@ public void testUpdateDividers_WithTabSelected() {
// Trigger update to set divider values.
mStripLayoutHelper.updateLayout(TIMESTAMP);

// Verify tabs 2 and 3's dividers are hidden due to selection.
float hiddenOpacity = StripLayoutHelper.DIVIDER_HIDDEN_OPACITY;
float visibleOpacity = StripLayoutHelper.DIVIDER_DEFAULT_OPACITY;
// clang-format off
assertEquals("First divider should always be hidden.",
hiddenOpacity, tabs[0].getDividerOpacity(), EPSILON);
assertEquals("Divider should be at default opacity.",
visibleOpacity, tabs[1].getDividerOpacity(), EPSILON);
assertEquals("Divider is adjacent to selected tab and should be hidden.",
hiddenOpacity, tabs[2].getDividerOpacity(), EPSILON);
assertEquals("Divider is adjacent to selected tab and should be hidden.",
hiddenOpacity, tabs[3].getDividerOpacity(), EPSILON);
assertEquals("Divider should be at default opacity.",
visibleOpacity, tabs[4].getDividerOpacity(), EPSILON);
// clang-format on
// Verify tabs 2 and 3's start dividers are hidden due to selection.
assertFalse(
"First start divider should always be hidden.", tabs[0].isStartDividerVisible());
assertTrue("Start divider should be visible.", tabs[1].isStartDividerVisible());
assertFalse("Start divider is for selected tab and should be hidden.",
tabs[2].isStartDividerVisible());
assertFalse("Start divider is adjacent to selected tab and should be hidden.",
tabs[3].isStartDividerVisible());
assertTrue("Start divider should be visible.", tabs[4].isStartDividerVisible());

// Verify only last tab's end divider is visible.
assertFalse("End divider should be hidden.", tabs[0].isEndDividerVisible());
assertFalse("End divider should be hidden.", tabs[1].isEndDividerVisible());
assertFalse("End divider should be hidden.", tabs[2].isEndDividerVisible());
assertFalse("End divider should be hidden.", tabs[3].isEndDividerVisible());
assertTrue("End divider should be visible.", tabs[4].isEndDividerVisible());
}

@Test
@Feature("Tab Strip Redesign")
public void testUpdateDividers_InReorderMode() {
// Setup with 5 tabs. Select 2nd tab.
initializeTest(false, false, true, 1, 5);
mStripLayoutHelper.onSizeChanged(SCREEN_WIDTH, SCREEN_HEIGHT, false, TIMESTAMP);
// group 2nd and 3rd tab.
groupTabs(1, 3);

// Start reorder mode at 2nd tab
mStripLayoutHelper.startReorderModeAtIndexForTesting(1);
// Trigger update to set divider values.
mStripLayoutHelper.updateLayout(TIMESTAMP);

StripLayoutTab[] tabs = mStripLayoutHelper.getStripLayoutTabs();
// Verify only 4th and 5th tab's start divider is visible.
assertFalse(
"First start divider should always be hidden.", tabs[0].isStartDividerVisible());
assertFalse("Start divider should be hidden.", tabs[1].isStartDividerVisible());
assertFalse("Start divider should be hidden.", tabs[2].isStartDividerVisible());
assertTrue("Start divider should be hidden.", tabs[3].isStartDividerVisible());
assertTrue("Start divider should be visible.", tabs[4].isStartDividerVisible());

// Verify end divider visible for 1st and 5th tab.
assertTrue("End divider should be visible.", tabs[0].isEndDividerVisible());
assertFalse("End divider should be hidden.", tabs[1].isEndDividerVisible());
assertFalse("End divider should be hidden.", tabs[2].isEndDividerVisible());
assertFalse("End divider should be hidden.", tabs[3].isEndDividerVisible());
assertTrue("End divider should be visible.", tabs[4].isEndDividerVisible());
}

@Test
Expand Down
53 changes: 33 additions & 20 deletions chrome/browser/android/compositor/layer/tab_handle_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ void TabHandleLayer::SetProperties(
float bottom_offset_y,
float close_button_padding,
float close_button_alpha,
float divider_alpha,
bool is_start_divider_visible,
bool is_end_divider_visible,
bool is_loading,
float spinner_rotation,
float brightness,
Expand Down Expand Up @@ -168,25 +169,36 @@ void TabHandleLayer::SetProperties(
}
}

if (divider_alpha == 0.f) {
divider_->SetIsDrawable(false);
int divider_y;
float divider_y_offset_mid =
(tab_handle_resource->padding().y() + height) / 2 -
start_divider_->bounds().height() / 2;
if (is_tab_strip_redesign_enabled) {
divider_y = content_offset_y;
} else {
divider_->SetIsDrawable(true);
divider_->SetUIResourceId(divider_resource->ui_resource()->id());
divider_->SetBounds(divider_resource->size());
divider_y = divider_y_offset_mid;
}

int divider_y;
float divider_y_offset_mid =
(tab_handle_resource->padding().y() + height) / 2 -
divider_->bounds().height() / 2;
if (is_tab_strip_redesign_enabled) {
divider_y = content_offset_y;
} else {
divider_y = divider_y_offset_mid;
}
if (!is_start_divider_visible) {
start_divider_->SetIsDrawable(false);
} else {
start_divider_->SetIsDrawable(true);
start_divider_->SetUIResourceId(divider_resource->ui_resource()->id());
start_divider_->SetBounds(divider_resource->size());
int divider_x = is_rtl ? width - divider_offset_x : divider_offset_x;
divider_->SetPosition(gfx::PointF(divider_x, divider_y));
divider_->SetOpacity(divider_alpha);
start_divider_->SetPosition(gfx::PointF(divider_x, divider_y));
start_divider_->SetOpacity(1.0f);
}

if (!is_end_divider_visible) {
end_divider_->SetIsDrawable(false);
} else {
end_divider_->SetIsDrawable(true);
end_divider_->SetUIResourceId(divider_resource->ui_resource()->id());
end_divider_->SetBounds(divider_resource->size());
int divider_x = is_rtl ? divider_offset_x : width - divider_offset_x;
end_divider_->SetPosition(gfx::PointF(divider_x, divider_y));
end_divider_->SetOpacity(1.0f);
}

if (title_layer) {
Expand Down Expand Up @@ -217,7 +229,6 @@ void TabHandleLayer::SetProperties(
title_layer->SetIsLoading(false);
}
}

if (close_button_alpha == 0.f) {
close_button_->SetIsDrawable(false);
} else {
Expand Down Expand Up @@ -255,7 +266,8 @@ TabHandleLayer::TabHandleLayer(LayerTitleCache* layer_title_cache)
layer_(cc::slim::Layer::Create()),
tab_(cc::slim::Layer::Create()),
close_button_(cc::slim::UIResourceLayer::Create()),
divider_(cc::slim::UIResourceLayer::Create()),
start_divider_(cc::slim::UIResourceLayer::Create()),
end_divider_(cc::slim::UIResourceLayer::Create()),
decoration_tab_(cc::slim::NinePatchLayer::Create()),
tab_outline_(cc::slim::NinePatchLayer::Create()),
brightness_(1.0f),
Expand All @@ -269,7 +281,8 @@ TabHandleLayer::TabHandleLayer(LayerTitleCache* layer_title_cache)
// The divider is added as a separate child so its opacity can be controlled
// separately from the other tab items.
layer_->AddChild(tab_);
layer_->AddChild(divider_);
layer_->AddChild(start_divider_);
layer_->AddChild(end_divider_);
}

TabHandleLayer::~TabHandleLayer() {
Expand Down
6 changes: 4 additions & 2 deletions chrome/browser/android/compositor/layer/tab_handle_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class TabHandleLayer : public Layer {
float bottom_offset_y,
float close_button_padding,
float close_button_alpha,
float divider_alpha,
bool is_start_divider_visible,
bool is_end_divider_visible,
bool is_loading,
float spinner_rotation,
float brightness,
Expand All @@ -67,7 +68,8 @@ class TabHandleLayer : public Layer {
scoped_refptr<cc::slim::Layer> layer_;
scoped_refptr<cc::slim::Layer> tab_;
scoped_refptr<cc::slim::UIResourceLayer> close_button_;
scoped_refptr<cc::slim::UIResourceLayer> divider_;
scoped_refptr<cc::slim::UIResourceLayer> start_divider_;
scoped_refptr<cc::slim::UIResourceLayer> end_divider_;
scoped_refptr<cc::slim::NinePatchLayer> decoration_tab_;
scoped_refptr<cc::slim::NinePatchLayer> tab_outline_;
scoped_refptr<cc::slim::Layer> title_layer_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,8 @@ void TabStripSceneLayer::PutStripTabLayer(
jfloat bottom_offset_y,
jfloat close_button_padding,
jfloat close_button_alpha,
jfloat divider_alpha,
jboolean is_start_divider_visible,
jboolean is_end_divider_visible,
jboolean is_loading,
jfloat spinner_rotation,
jfloat brightness,
Expand All @@ -440,9 +441,9 @@ void TabStripSceneLayer::PutStripTabLayer(
id, close_button_resource, divider_resource, tab_handle_resource,
tab_handle_outline_resource, foreground, close_pressed, toolbar_width, x,
y, width, height, content_offset_x, content_offset_y, divider_offset_x,
bottom_offset_y, close_button_padding, close_button_alpha, divider_alpha,
is_loading, spinner_rotation, brightness, opacity,
tab_strip_redesign_enabled);
bottom_offset_y, close_button_padding, close_button_alpha,
is_start_divider_visible, is_end_divider_visible, is_loading,
spinner_rotation, brightness, opacity, tab_strip_redesign_enabled);
}

scoped_refptr<TabHandleLayer> TabStripSceneLayer::GetNextLayer(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ class TabStripSceneLayer : public SceneLayer {
jfloat bottom_offset_y,
jfloat close_button_padding,
jfloat close_button_alpha,
jfloat divider_alpha,
jboolean is_start_divider_visible,
jboolean is_end_divider_visible,
jboolean is_loading,
jfloat spinner_rotation,
jfloat brightness,
Expand Down

0 comments on commit d4c5b7d

Please sign in to comment.