Commit 9ffdcdbf authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Refactor usage of GetTabEndcapWidth()/GetCornerRadius().

The pre-refresh use of "endcap" isn't quite as clear in refresh, where tabs
appear to start suddenly at a point that turns out to be halfway through the
"endcap".  Instead, restrict usage of GetTabEndcapWidth() (now renamed for
parallelism with GetTabEndcapWidthForPainting()) to pre-refresh.  In refresh,
use GetCornerRadius(), whose relationship to the tab's appearance is more clear.

This adds a new GetContentsInsets() static method as well, which allows
decoupling the concept of the endcap width/corner radius from "how far into the
tab bounds does content start", which is what a number of callers really care
about.  Removing dependencies on GetMinimumInactiveTabWidth() will be useful for
allowing narrower tabs.

Bug: none
Change-Id: Ic749c4b3f1b2c3611db0fa4966d62513367aec51
Reviewed-on: https://chromium-review.googlesource.com/1121818Reviewed-by: default avatarAllen Bauer <kylixrd@chromium.org>
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#572024}
parent d7b8b011
...@@ -124,20 +124,25 @@ int Center(int size, int item_size) { ...@@ -124,20 +124,25 @@ int Center(int size, int item_size) {
return extra_space / 2; return extra_space / 2;
} }
// Returns the width of the tab endcap in DIP. Pre-refresh, this is the // For non-material-refresh mode, returns the width of the tab endcap in DIP.
// width of the curve making up either the outer or inner edge of the stroke. // More precisely, this is the width of the curve making up either the outer or
int GetTabEndcapWidth() { // inner edge of the stroke.
constexpr int kEndcapWidth[] = {16, 18, 24, 16, 16}; //
return kEndcapWidth[MD::GetMode()]; // These two curves are horizontally offset by 1 px (regardless of scale); the
} // total width of the endcap from tab outer edge to the inside end of the stroke
// inner edge is (GetTabEndcapWidthForLayout() * scale) + 1.
// Pre-refresh, endcaps paint slightly differently than they layout. int GetTabEndcapWidthForLayout() {
const int mode = MD::GetMode();
DCHECK_LE(mode, 2);
constexpr int kEndcapWidth[] = {16, 18, 24};
return kEndcapWidth[mode];
}
// For painting the endcaps, the top corners are actually shifted outwards 0.5
// DIP from the grid.
float GetTabEndcapWidthForPainting() { float GetTabEndcapWidthForPainting() {
DCHECK(!MD::IsRefreshUi()); return GetTabEndcapWidthForLayout() - 0.5f;
// For painting the endcaps, the top corners are actually shifted outwards 0.5
// DIP from the grid.
return GetTabEndcapWidth() - 0.5f;
} }
void DrawHighlight(gfx::Canvas* canvas, void DrawHighlight(gfx::Canvas* canvas,
...@@ -156,12 +161,11 @@ void DrawHighlight(gfx::Canvas* canvas, ...@@ -156,12 +161,11 @@ void DrawHighlight(gfx::Canvas* canvas,
// Scales |bounds| by scale and aligns so that the layout portion is snapped to // Scales |bounds| by scale and aligns so that the layout portion is snapped to
// the pixel grid. This ensures adjacent tabs meet up exactly during painting. // the pixel grid. This ensures adjacent tabs meet up exactly during painting.
const gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, const gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, float scale) {
float endcap_width,
float scale) {
// Convert full bounds to layout bounds and scale from DIP to px. // Convert full bounds to layout bounds and scale from DIP to px.
gfx::RectF aligned_bounds(bounds); gfx::RectF aligned_bounds(bounds);
aligned_bounds.Inset(endcap_width / 2, 0); const int corner_radius = Tab::GetCornerRadius();
aligned_bounds.Inset(corner_radius, 0);
aligned_bounds.Scale(scale); aligned_bounds.Scale(scale);
// Snap layout bounds to nearest pixels. // Snap layout bounds to nearest pixels.
...@@ -177,7 +181,7 @@ const gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, ...@@ -177,7 +181,7 @@ const gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds,
// Convert back to full bounds. The endcap widths are not rounded, since it's // Convert back to full bounds. The endcap widths are not rounded, since it's
// OK if the corners do not snap to the pixel grid. // OK if the corners do not snap to the pixel grid.
aligned_bounds.Inset(-(endcap_width / 2) * scale, 0); aligned_bounds.Inset(-corner_radius * scale, 0);
return aligned_bounds; return aligned_bounds;
} }
...@@ -197,11 +201,12 @@ gfx::Path OffsetAndIntersectPaths(gfx::Path& left_path, ...@@ -197,11 +201,12 @@ gfx::Path OffsetAndIntersectPaths(gfx::Path& left_path,
gfx::Path GetRefreshInteriorPath(float scale, gfx::Path GetRefreshInteriorPath(float scale,
const gfx::Rect& bounds, const gfx::Rect& bounds,
float horizontal_inset) { float horizontal_inset) {
const float endcap_width = GetTabEndcapWidth(); // TODO(pkasting): Fix this to work better with stroke heights > 0.
const float radius = (endcap_width / 2) * scale;
const int ideal_radius = Tab::GetCornerRadius();
const float radius = ideal_radius * scale;
const gfx::RectF aligned_bounds = const gfx::RectF aligned_bounds = ScaleAndAlignBounds(bounds, scale);
ScaleAndAlignBounds(bounds, endcap_width, scale);
const float left = aligned_bounds.x(); const float left = aligned_bounds.x();
const float top = aligned_bounds.y() + Tab::GetStrokeHeight(); const float top = aligned_bounds.y() + Tab::GetStrokeHeight();
const float right = aligned_bounds.right(); const float right = aligned_bounds.right();
...@@ -310,12 +315,13 @@ gfx::Path GetRefreshBorderPath(const gfx::Rect& bounds, ...@@ -310,12 +315,13 @@ gfx::Path GetRefreshBorderPath(const gfx::Rect& bounds,
bool extend_to_top, bool extend_to_top,
float scale, float scale,
float stroke_thickness) { float stroke_thickness) {
const float endcap_width = GetTabEndcapWidth(); // TODO(pkasting): Fix this to work better with stroke heights > 0.
const float outer_radius = (endcap_width / 2) * scale - stroke_thickness;
const float inner_radius = (endcap_width / 2) * scale + stroke_thickness;
const gfx::RectF aligned_bounds = const float ideal_radius = Tab::GetCornerRadius();
ScaleAndAlignBounds(bounds, endcap_width, scale); const float outer_radius = ideal_radius * scale - stroke_thickness;
const float inner_radius = ideal_radius * scale + stroke_thickness;
const gfx::RectF aligned_bounds = ScaleAndAlignBounds(bounds, scale);
const float left = aligned_bounds.x(); const float left = aligned_bounds.x();
const float top = aligned_bounds.y(); const float top = aligned_bounds.y();
const float right = aligned_bounds.right(); const float right = aligned_bounds.right();
...@@ -463,8 +469,7 @@ Tab::Tab(TabController* controller, gfx::AnimationContainer* container) ...@@ -463,8 +469,7 @@ Tab::Tab(TabController* controller, gfx::AnimationContainer* container)
// This will cause calls to GetContentsBounds to return only the rectangle // This will cause calls to GetContentsBounds to return only the rectangle
// inside the tab shape, rather than to its extents. // inside the tab shape, rather than to its extents.
SetBorder(views::CreateEmptyBorder( SetBorder(views::CreateEmptyBorder(GetContentsInsets()));
gfx::Insets(GetStrokeHeight(), GetTabEndcapWidth())));
title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
title_->SetElideBehavior(gfx::FADE_TAIL); title_->SetElideBehavior(gfx::FADE_TAIL);
...@@ -912,12 +917,6 @@ void Tab::OnThemeChanged() { ...@@ -912,12 +917,6 @@ void Tab::OnThemeChanged() {
OnButtonColorMaybeChanged(); OnButtonColorMaybeChanged();
} }
int Tab::GetCornerRadius() const {
// TODO(pkasting): This should vary as the tab width decreases.
return ChromeLayoutProvider::Get()->GetCornerRadiusMetric(
views::EMPHASIS_HIGH);
}
SkColor Tab::GetAlertIndicatorColor(TabAlertState state) const { SkColor Tab::GetAlertIndicatorColor(TabAlertState state) const {
const bool is_touch_optimized = MD::IsTouchOptimizedUiEnabled(); const bool is_touch_optimized = MD::IsTouchOptimizedUiEnabled();
// If theme provider is not yet available, return the default button // If theme provider is not yet available, return the default button
...@@ -1089,12 +1088,12 @@ void Tab::FrameColorsChanged() { ...@@ -1089,12 +1088,12 @@ void Tab::FrameColorsChanged() {
// static // static
int Tab::GetMinimumInactiveWidth() { int Tab::GetMinimumInactiveWidth() {
return GetTabEndcapWidth() * 2; return GetContentsInsets().width();
} }
// static // static
int Tab::GetMinimumActiveWidth() { int Tab::GetMinimumActiveWidth() {
return TabCloseButton::GetWidth() + GetMinimumInactiveWidth(); return TabCloseButton::GetWidth() + GetContentsInsets().width();
} }
// static // static
...@@ -1106,7 +1105,7 @@ int Tab::GetStandardWidth() { ...@@ -1106,7 +1105,7 @@ int Tab::GetStandardWidth() {
// static // static
int Tab::GetPinnedWidth() { int Tab::GetPinnedWidth() {
constexpr int kTabPinnedContentWidth = 23; constexpr int kTabPinnedContentWidth = 23;
return kTabPinnedContentWidth + GetMinimumInactiveWidth(); return kTabPinnedContentWidth + GetContentsInsets().width();
} }
// static // static
...@@ -1123,7 +1122,7 @@ float Tab::GetInverseDiagonalSlope() { ...@@ -1123,7 +1122,7 @@ float Tab::GetInverseDiagonalSlope() {
// * The endcap width is enough for the whole stroke outer curve, i.e. the // * The endcap width is enough for the whole stroke outer curve, i.e. the
// side diagonal plus the curves on both its ends. // side diagonal plus the curves on both its ends.
// * The bottom and top curve together are 4 DIP wide, so the diagonal is // * The bottom and top curve together are 4 DIP wide, so the diagonal is
// (endcap_width - 4) DIP wide. // (endcap width - 4) DIP wide.
// * The bottom and top curve are each 1.5 px high. Additionally, there is an // * The bottom and top curve are each 1.5 px high. Additionally, there is an
// extra 1 px below the bottom curve and (scale - 1) px above the top curve, // extra 1 px below the bottom curve and (scale - 1) px above the top curve,
// so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px // so the diagonal is ((height - 1.5 - 1.5) * scale - 1 - (scale - 1)) px
...@@ -1133,11 +1132,24 @@ float Tab::GetInverseDiagonalSlope() { ...@@ -1133,11 +1132,24 @@ float Tab::GetInverseDiagonalSlope() {
(GetLayoutConstant(TAB_HEIGHT) - 4); (GetLayoutConstant(TAB_HEIGHT) - 4);
} }
// static
int Tab::GetCornerRadius() {
return ChromeLayoutProvider::Get()->GetCornerRadiusMetric(
views::EMPHASIS_HIGH);
}
// static
gfx::Insets Tab::GetContentsInsets() {
const int endcap_width = MD::IsRefreshUi() ? (GetCornerRadius() * 2)
: GetTabEndcapWidthForLayout();
return gfx::Insets(GetStrokeHeight(), endcap_width);
}
// static // static
int Tab::GetOverlap() { int Tab::GetOverlap() {
// We want to overlap the endcap portions entirely. Under refresh, we want to // For refresh, overlap the separators.
// overlap by an extra dip on each end in order overlap the separators. return MD::IsRefreshUi() ? (GetCornerRadius() * 2 + kSeparatorThickness)
return GetTabEndcapWidth() + (MD::IsRefreshUi() ? kSeparatorThickness : 0); : GetTabEndcapWidthForLayout();
} }
// static // static
...@@ -1355,18 +1367,15 @@ void Tab::PaintSeparators(gfx::Canvas* canvas) { ...@@ -1355,18 +1367,15 @@ void Tab::PaintSeparators(gfx::Canvas* canvas) {
gfx::ScopedCanvas scoped_canvas(canvas); gfx::ScopedCanvas scoped_canvas(canvas);
const float scale = canvas->UndoDeviceScaleFactor(); const float scale = canvas->UndoDeviceScaleFactor();
const float endcap_width = GetTabEndcapWidth(); const gfx::RectF aligned_bounds = ScaleAndAlignBounds(bounds(), scale);
const gfx::RectF aligned_bounds = const int corner_radius = GetCornerRadius();
ScaleAndAlignBounds(bounds(), endcap_width, scale);
const float separator_height = GetTabSeparatorHeight() * scale; const float separator_height = GetTabSeparatorHeight() * scale;
gfx::RectF leading_separator_bounds( gfx::RectF leading_separator_bounds(
aligned_bounds.x() + (endcap_width / 2) * scale, aligned_bounds.x() + corner_radius * scale,
aligned_bounds.y() + (aligned_bounds.height() - separator_height) / 2, aligned_bounds.y() + (aligned_bounds.height() - separator_height) / 2,
kSeparatorThickness * scale, separator_height); kSeparatorThickness * scale, separator_height);
gfx::RectF trailing_separator_bounds( gfx::RectF trailing_separator_bounds(
aligned_bounds.right() - (endcap_width / 2) * scale - aligned_bounds.right() - (corner_radius + kSeparatorThickness) * scale,
kSeparatorThickness * scale,
leading_separator_bounds.y(), kSeparatorThickness * scale, leading_separator_bounds.y(), kSeparatorThickness * scale,
separator_height); separator_height);
...@@ -1439,7 +1448,7 @@ void Tab::UpdateIconVisibility() { ...@@ -1439,7 +1448,7 @@ void Tab::UpdateIconVisibility() {
if (height() < GetLayoutConstant(TAB_HEIGHT)) if (height() < GetLayoutConstant(TAB_HEIGHT))
return; return;
int available_width = std::max(0, width() - GetMinimumInactiveWidth()); int available_width = GetContentsBounds().width();
const bool is_touch_optimized = MD::IsTouchOptimizedUiEnabled(); const bool is_touch_optimized = MD::IsTouchOptimizedUiEnabled();
const int favicon_width = gfx::kFaviconSize; const int favicon_width = gfx::kFaviconSize;
......
...@@ -110,9 +110,6 @@ class Tab : public gfx::AnimationDelegate, ...@@ -110,9 +110,6 @@ class Tab : public gfx::AnimationDelegate,
void set_detached() { detached_ = true; } void set_detached() { detached_ = true; }
bool detached() const { return detached_; } bool detached() const { return detached_; }
// Returns the radius of the outer corners of the tab shape.
int GetCornerRadius() const;
// Returns the color used for the alert indicator icon. // Returns the color used for the alert indicator icon.
SkColor GetAlertIndicatorColor(TabAlertState state) const; SkColor GetAlertIndicatorColor(TabAlertState state) const;
...@@ -204,6 +201,12 @@ class Tab : public gfx::AnimationDelegate, ...@@ -204,6 +201,12 @@ class Tab : public gfx::AnimationDelegate,
// horizontal deltas from those. // horizontal deltas from those.
static float GetInverseDiagonalSlope(); static float GetInverseDiagonalSlope();
// Returns the radius of the outer corners of the tab shape.
static int GetCornerRadius();
// Returns the insets to use for laying out tab contents.
static gfx::Insets GetContentsInsets();
// Returns the overlap between adjacent tabs. // Returns the overlap between adjacent tabs.
static int GetOverlap(); static int GetOverlap();
......
...@@ -1351,7 +1351,7 @@ void TabStrip::OnPaint(gfx::Canvas* canvas) { ...@@ -1351,7 +1351,7 @@ void TabStrip::OnPaint(gfx::Canvas* canvas) {
if (MD::IsRefreshUi() && GetNewTabButtonPosition() == TRAILING) { if (MD::IsRefreshUi() && GetNewTabButtonPosition() == TRAILING) {
float separator_height = Tab::GetTabSeparatorHeight(); float separator_height = Tab::GetTabSeparatorHeight();
gfx::RectF separator_bounds( gfx::RectF separator_bounds(
new_tab_button_bounds_.x() - Tab::GetOverlap() / 2, new_tab_button_bounds_.x() - Tab::GetCornerRadius(),
(height() - separator_height) / 2, 1, separator_height); (height() - separator_height) / 2, 1, separator_height);
cc::PaintFlags flags; cc::PaintFlags flags;
flags.setAntiAlias(true); flags.setAntiAlias(true);
...@@ -1611,7 +1611,7 @@ int TabStrip::GetFrameGrabWidth() const { ...@@ -1611,7 +1611,7 @@ int TabStrip::GetFrameGrabWidth() const {
// space where the outer (lower) corners are, which should be treated as // space where the outer (lower) corners are, which should be treated as
// part of the grab area, so decrease the size of the remaining grab area by // part of the grab area, so decrease the size of the remaining grab area by
// that width. // that width.
width -= tab_at(tab_count() - 1)->GetCornerRadius(); width -= Tab::GetCornerRadius();
} }
return width; return width;
......
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