Commit 53bcedc8 authored by Bret Sepulveda's avatar Bret Sepulveda Committed by Commit Bot

Hide the tab's close-x in Refresh's single-tab mode.

This patch refactors the single tab mode to be tracked by the tabstrip,
and enabled/disabled by BrowserNonClientFrameView when appropriate. The
tabstrip uses that mode flag to force the close-x for the active tab to
be invisible.

Bug: 841643
Change-Id: I0c8713e5190af935d665e7d10f984db8624b4ab0
Reviewed-on: https://chromium-review.googlesource.com/1068214
Commit-Queue: Bret Sepulveda <bsep@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563109}
parent 74fffb29
...@@ -119,6 +119,13 @@ void BrowserNonClientFrameView::ChildPreferredSizeChanged(views::View* child) { ...@@ -119,6 +119,13 @@ void BrowserNonClientFrameView::ChildPreferredSizeChanged(views::View* child) {
} }
} }
void BrowserNonClientFrameView::OnThemeChanged() {
// Adding or removing a frame image will change whether single tab mode is
// available.
if (MD::IsRefreshUi() && browser_view()->IsTabStripVisible())
browser_view()->tabstrip()->SingleTabModeChanged();
}
void BrowserNonClientFrameView::VisibilityChanged(views::View* starting_from, void BrowserNonClientFrameView::VisibilityChanged(views::View* starting_from,
bool is_visible) { bool is_visible) {
// UpdateTaskbarDecoration() calls DrawTaskbarDecoration(), but that does // UpdateTaskbarDecoration() calls DrawTaskbarDecoration(), but that does
...@@ -130,15 +137,15 @@ void BrowserNonClientFrameView::VisibilityChanged(views::View* starting_from, ...@@ -130,15 +137,15 @@ void BrowserNonClientFrameView::VisibilityChanged(views::View* starting_from,
} }
void BrowserNonClientFrameView::OnTabAdded(int index) { void BrowserNonClientFrameView::OnTabAdded(int index) {
if (MD::IsRefreshUi() && browser_view()->tabstrip()->tab_count() == 2) { if (IsSingleTabModeAvailable()) {
// We are exiting single-tab mode and need to repaint the frame. // We may be exiting single-tab mode and need to repaint the frame.
SchedulePaint(); SchedulePaint();
} }
} }
void BrowserNonClientFrameView::OnTabRemoved(int index) { void BrowserNonClientFrameView::OnTabRemoved(int index) {
if (MD::IsRefreshUi() && browser_view()->tabstrip()->tab_count() == 1) { if (IsSingleTabModeAvailable()) {
// We are entering single-tab mode and need to repaint the frame. // We may be entering single-tab mode and need to repaint the frame.
SchedulePaint(); SchedulePaint();
} }
} }
...@@ -147,13 +154,16 @@ bool BrowserNonClientFrameView::ShouldPaintAsThemed() const { ...@@ -147,13 +154,16 @@ bool BrowserNonClientFrameView::ShouldPaintAsThemed() const {
return browser_view_->IsBrowserTypeNormal(); return browser_view_->IsBrowserTypeNormal();
} }
bool BrowserNonClientFrameView::ShouldPaintAsSingleTabMode() const { bool BrowserNonClientFrameView::IsSingleTabModeAvailable() const {
// Single-tab mode is only available in Refresh. The special color we use for // Single-tab mode is only available in Refresh. The special color we use
// won't be visible if there's a frame image, but since it's used to determine // won't be visible if there's a frame image, but since it's used to determine
// constrast of other UI elements, the theme color should be used instead. // constrast of other UI elements, the theme color should be used instead.
return MD::IsRefreshUi() && GetFrameImage().isNull() && return MD::IsRefreshUi() && GetFrameImage().isNull();
browser_view()->IsTabStripVisible() && }
browser_view()->tabstrip()->tab_count() == 1;
bool BrowserNonClientFrameView::ShouldPaintAsSingleTabMode() const {
return browser_view()->IsTabStripVisible() &&
browser_view()->tabstrip()->SingleTabMode();
} }
SkColor BrowserNonClientFrameView::GetFrameColor(bool active) const { SkColor BrowserNonClientFrameView::GetFrameColor(bool active) const {
......
...@@ -90,8 +90,13 @@ class BrowserNonClientFrameView : public views::NonClientFrameView, ...@@ -90,8 +90,13 @@ class BrowserNonClientFrameView : public views::NonClientFrameView,
// https://crbug.com/820485. // https://crbug.com/820485.
virtual int GetTabStripLeftInset() const; virtual int GetTabStripLeftInset() const;
// Whether the special painting mode for one tab is allowed, regardless of how
// many tabs there are right now.
bool IsSingleTabModeAvailable() const;
// views::NonClientFrameView: // views::NonClientFrameView:
void ChildPreferredSizeChanged(views::View* child) override; void ChildPreferredSizeChanged(views::View* child) override;
void OnThemeChanged() override;
void VisibilityChanged(views::View* starting_from, bool is_visible) override; void VisibilityChanged(views::View* starting_from, bool is_visible) override;
// TabStripObserver: // TabStripObserver:
...@@ -104,7 +109,7 @@ class BrowserNonClientFrameView : public views::NonClientFrameView, ...@@ -104,7 +109,7 @@ class BrowserNonClientFrameView : public views::NonClientFrameView,
// not. // not.
virtual bool ShouldPaintAsThemed() const; virtual bool ShouldPaintAsThemed() const;
// Whether the frame should be painted with a special mode for one tab. // Whether the frame should be painted with the special mode for one tab.
bool ShouldPaintAsSingleTabMode() const; bool ShouldPaintAsSingleTabMode() const;
// Compute aspects of the frame needed to paint the frame background. // Compute aspects of the frame needed to paint the frame background.
......
...@@ -346,6 +346,10 @@ void BrowserTabStripController::StackedLayoutMaybeChanged() { ...@@ -346,6 +346,10 @@ void BrowserTabStripController::StackedLayoutMaybeChanged() {
tabstrip_->stacked_layout()); tabstrip_->stacked_layout());
} }
bool BrowserTabStripController::IsSingleTabModeAvailable() {
return browser_view_->frame()->GetFrameView()->IsSingleTabModeAvailable();
}
void BrowserTabStripController::OnStartedDraggingTabs() { void BrowserTabStripController::OnStartedDraggingTabs() {
if (!immersive_reveal_lock_.get()) { if (!immersive_reveal_lock_.get()) {
// The top-of-window views should be revealed while the user is dragging // The top-of-window views should be revealed while the user is dragging
......
...@@ -70,6 +70,7 @@ class BrowserTabStripController : public TabStripController, ...@@ -70,6 +70,7 @@ class BrowserTabStripController : public TabStripController,
void CreateNewTabWithLocation(const base::string16& loc) override; void CreateNewTabWithLocation(const base::string16& loc) override;
bool IsIncognito() override; bool IsIncognito() override;
void StackedLayoutMaybeChanged() override; void StackedLayoutMaybeChanged() override;
bool IsSingleTabModeAvailable() override;
void OnStartedDraggingTabs() override; void OnStartedDraggingTabs() override;
void OnStoppedDraggingTabs() override; void OnStoppedDraggingTabs() override;
SkColor GetToolbarTopSeparatorColor() const override; SkColor GetToolbarTopSeparatorColor() const override;
......
...@@ -128,6 +128,10 @@ bool FakeBaseTabStripController::IsIncognito() { ...@@ -128,6 +128,10 @@ bool FakeBaseTabStripController::IsIncognito() {
void FakeBaseTabStripController::StackedLayoutMaybeChanged() { void FakeBaseTabStripController::StackedLayoutMaybeChanged() {
} }
bool FakeBaseTabStripController::IsSingleTabModeAvailable() {
return false;
}
void FakeBaseTabStripController::OnStartedDraggingTabs() { void FakeBaseTabStripController::OnStartedDraggingTabs() {
} }
......
...@@ -47,6 +47,7 @@ class FakeBaseTabStripController : public TabStripController { ...@@ -47,6 +47,7 @@ class FakeBaseTabStripController : public TabStripController {
void CreateNewTabWithLocation(const base::string16& loc) override; void CreateNewTabWithLocation(const base::string16& loc) override;
bool IsIncognito() override; bool IsIncognito() override;
void StackedLayoutMaybeChanged() override; void StackedLayoutMaybeChanged() override;
bool IsSingleTabModeAvailable() override;
void OnStartedDraggingTabs() override; void OnStartedDraggingTabs() override;
void OnStoppedDraggingTabs() override; void OnStoppedDraggingTabs() override;
SkColor GetToolbarTopSeparatorColor() const override; SkColor GetToolbarTopSeparatorColor() const override;
......
...@@ -1343,7 +1343,7 @@ void Tab::PaintSeparator(gfx::Canvas* canvas, SkColor inactive_color) { ...@@ -1343,7 +1343,7 @@ void Tab::PaintSeparator(gfx::Canvas* canvas, SkColor inactive_color) {
void Tab::UpdateIconVisibility() { void Tab::UpdateIconVisibility() {
center_favicon_ = false; center_favicon_ = false;
showing_icon_ = showing_alert_indicator_ = showing_close_button_ = false; showing_icon_ = showing_alert_indicator_ = false;
extra_padding_before_content_ = false; extra_padding_before_content_ = false;
const gfx::Size min_size(GetMinimumInactiveSize()); const gfx::Size min_size(GetMinimumInactiveSize());
...@@ -1371,10 +1371,6 @@ void Tab::UpdateIconVisibility() { ...@@ -1371,10 +1371,6 @@ void Tab::UpdateIconVisibility() {
const bool has_alert_icon = const bool has_alert_icon =
(alert_indicator_button_ ? alert_indicator_button_->showing_alert_state() (alert_indicator_button_ ? alert_indicator_button_->showing_alert_state()
: data().alert_state) != TabAlertState::NONE; : data().alert_state) != TabAlertState::NONE;
const bool hide_inactive_close_button =
controller_->ShouldHideCloseButtonForInactiveTabs();
const bool show_close_button_on_hover =
controller_->ShouldShowCloseButtonOnHover();
if (is_pinned) { if (is_pinned) {
// When the tab is pinned, we can show one of the two icons. Alert icon // When the tab is pinned, we can show one of the two icons. Alert icon
...@@ -1382,10 +1378,10 @@ void Tab::UpdateIconVisibility() { ...@@ -1382,10 +1378,10 @@ void Tab::UpdateIconVisibility() {
// tab is pinned. // tab is pinned.
showing_alert_indicator_ = has_alert_icon; showing_alert_indicator_ = has_alert_icon;
showing_icon_ = has_favicon && !has_alert_icon; showing_icon_ = has_favicon && !has_alert_icon;
showing_close_button_ = false;
} else { } else {
showing_close_button_ = !controller_->ShouldHideCloseButtonForTab(this);
if (is_active) { if (is_active) {
// The close button is always visible for an active tab.
showing_close_button_ = true;
available_width -= close_button_width; available_width -= close_button_width;
showing_alert_indicator_ = showing_alert_indicator_ =
...@@ -1412,18 +1408,17 @@ void Tab::UpdateIconVisibility() { ...@@ -1412,18 +1408,17 @@ void Tab::UpdateIconVisibility() {
if (!showing_icon_ || !showing_alert_indicator_) if (!showing_icon_ || !showing_alert_indicator_)
extra_padding = 0; extra_padding = 0;
// For an inactive tab, the close button will be visible only when // Show the close button if it's allowed to show on hover, even if it's
// it is not forced to hide and the total width can accomodate all 3 // forced to be hidden normally.
// icons. When favicon or alert button is not visible, its space showing_close_button_ |= controller_->ShouldShowCloseButtonOnHover() &&
// will be occupied by the title of this tab. hover_controller_.ShouldDraw();
// Always hide the close button if the total width can't accomodate all 3
// icons. When favicon or alert button is not visible, its space will be
// occupied by the title of this tab.
int title_width = int title_width =
(!showing_icon_ + !showing_alert_indicator_) * favicon_width; (!showing_icon_ + !showing_alert_indicator_) * favicon_width;
if ((!hide_inactive_close_button || if (title_width + close_button_width + extra_padding > available_width)
(show_close_button_on_hover && hover_controller_.ShouldDraw())) && showing_close_button_ = false;
(title_width + close_button_width + extra_padding <=
available_width)) {
showing_close_button_ = true;
}
// If no other controls are visible, show favicon even though we // If no other controls are visible, show favicon even though we
// don't have enough space. We'll clip the favicon in PaintChildren(). // don't have enough space. We'll clip the favicon in PaintChildren().
......
...@@ -60,6 +60,27 @@ class Tab : public gfx::AnimationDelegate, ...@@ -60,6 +60,27 @@ class Tab : public gfx::AnimationDelegate,
Tab(TabController* controller, gfx::AnimationContainer* container); Tab(TabController* controller, gfx::AnimationContainer* container);
~Tab() override; ~Tab() override;
// views::View:
void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) override;
void OnPaint(gfx::Canvas* canvas) override;
void PaintChildren(const views::PaintInfo& info) override;
void Layout() override;
void OnThemeChanged() override;
const char* GetClassName() const override;
bool GetTooltipText(const gfx::Point& p,
base::string16* tooltip) const override;
bool GetTooltipTextOrigin(const gfx::Point& p,
gfx::Point* origin) const override;
bool OnMousePressed(const ui::MouseEvent& event) override;
bool OnMouseDragged(const ui::MouseEvent& event) override;
void OnMouseReleased(const ui::MouseEvent& event) override;
void OnMouseCaptureLost() override;
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseMoved(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
TabController* controller() const { return controller_; } TabController* controller() const { return controller_; }
// Used to set/check whether this Tab is being animated closed. // Used to set/check whether this Tab is being animated closed.
...@@ -133,10 +154,6 @@ class Tab : public gfx::AnimationDelegate, ...@@ -133,10 +154,6 @@ class Tab : public gfx::AnimationDelegate,
// user to click to select/activate the tab. // user to click to select/activate the tab.
int GetWidthOfLargestSelectableRegion() const; int GetWidthOfLargestSelectableRegion() const;
// Called when stacked layout changes and the close button may need to
// be updated.
void HideCloseButtonForInactiveTabsChanged() { Layout(); }
// Returns the minimum possible size of a single unselected Tab. // Returns the minimum possible size of a single unselected Tab.
static gfx::Size GetMinimumInactiveSize(); static gfx::Size GetMinimumInactiveSize();
...@@ -187,27 +204,6 @@ class Tab : public gfx::AnimationDelegate, ...@@ -187,27 +204,6 @@ class Tab : public gfx::AnimationDelegate,
// views::MaskedTargeterDelegate: // views::MaskedTargeterDelegate:
bool GetHitTestMask(gfx::Path* mask) const override; bool GetHitTestMask(gfx::Path* mask) const override;
// views::View:
void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) override;
void OnPaint(gfx::Canvas* canvas) override;
void PaintChildren(const views::PaintInfo& info) override;
void Layout() override;
void OnThemeChanged() override;
const char* GetClassName() const override;
bool GetTooltipText(const gfx::Point& p,
base::string16* tooltip) const override;
bool GetTooltipTextOrigin(const gfx::Point& p,
gfx::Point* origin) const override;
bool OnMousePressed(const ui::MouseEvent& event) override;
bool OnMouseDragged(const ui::MouseEvent& event) override;
void OnMouseReleased(const ui::MouseEvent& event) override;
void OnMouseCaptureLost() override;
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseMoved(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
// ui::EventHandler: // ui::EventHandler:
void OnGestureEvent(ui::GestureEvent* event) override; void OnGestureEvent(ui::GestureEvent* event) override;
......
...@@ -39,9 +39,8 @@ class TabController { ...@@ -39,9 +39,8 @@ class TabController {
// Returns true if multiple selection is supported. // Returns true if multiple selection is supported.
virtual bool SupportsMultipleSelection() = 0; virtual bool SupportsMultipleSelection() = 0;
// Returns true if the close buttons of the inactive tabs are forced to be // Returns true if the close button for the given tab is forced to be hidden.
// hidden. virtual bool ShouldHideCloseButtonForTab(Tab* tab) const = 0;
virtual bool ShouldHideCloseButtonForInactiveTabs() = 0;
// Returns true if the close button on an inactive tab should be shown on // Returns true if the close button on an inactive tab should be shown on
// mouse hover. This is predicated on ShouldHideCloseButtonForInactiveTabs() // mouse hover. This is predicated on ShouldHideCloseButtonForInactiveTabs()
......
...@@ -409,7 +409,11 @@ void TabStrip::SetStackedLayout(bool stacked_layout) { ...@@ -409,7 +409,11 @@ void TabStrip::SetStackedLayout(bool stacked_layout) {
} }
for (int i = 0; i < tab_count(); ++i) for (int i = 0; i < tab_count(); ++i)
tab_at(i)->HideCloseButtonForInactiveTabsChanged(); tab_at(i)->Layout();
}
bool TabStrip::SingleTabMode() const {
return controller_->IsSingleTabModeAvailable() && tab_count() == 1;
} }
bool TabStrip::SizeTabButtonToTopOfTabStrip() { bool TabStrip::SizeTabButtonToTopOfTabStrip() {
...@@ -429,6 +433,8 @@ void TabStrip::StopAllHighlighting() { ...@@ -429,6 +433,8 @@ void TabStrip::StopAllHighlighting() {
} }
void TabStrip::AddTabAt(int model_index, TabRendererData data, bool is_active) { void TabStrip::AddTabAt(int model_index, TabRendererData data, bool is_active) {
const bool was_single_tab_mode = SingleTabMode();
Tab* tab = new Tab(this, animation_container_.get()); Tab* tab = new Tab(this, animation_container_.get());
AddChildView(tab); AddChildView(tab);
const bool pinned = data.pinned; const bool pinned = data.pinned;
...@@ -456,6 +462,9 @@ void TabStrip::AddTabAt(int model_index, TabRendererData data, bool is_active) { ...@@ -456,6 +462,9 @@ void TabStrip::AddTabAt(int model_index, TabRendererData data, bool is_active) {
SwapLayoutIfNecessary(); SwapLayoutIfNecessary();
if (was_single_tab_mode)
SingleTabModeChanged();
for (TabStripObserver& observer : observers_) for (TabStripObserver& observer : observers_)
observer.OnTabAdded(model_index); observer.OnTabAdded(model_index);
...@@ -525,6 +534,9 @@ void TabStrip::RemoveTabAt(content::WebContents* contents, int model_index) { ...@@ -525,6 +534,9 @@ void TabStrip::RemoveTabAt(content::WebContents* contents, int model_index) {
for (TabStripObserver& observer : observers_) for (TabStripObserver& observer : observers_)
observer.OnTabRemoved(model_index); observer.OnTabRemoved(model_index);
if (SingleTabMode())
SingleTabModeChanged();
// Stop dragging when a new tab is removed and dragging a window. Doing // Stop dragging when a new tab is removed and dragging a window. Doing
// otherwise results in a confusing state if the user attempts to reattach. We // otherwise results in a confusing state if the user attempts to reattach. We
// could allow this and make TabDragController update itself during the // could allow this and make TabDragController update itself during the
...@@ -781,7 +793,9 @@ bool TabStrip::SupportsMultipleSelection() { ...@@ -781,7 +793,9 @@ bool TabStrip::SupportsMultipleSelection() {
return touch_layout_ == nullptr; return touch_layout_ == nullptr;
} }
bool TabStrip::ShouldHideCloseButtonForInactiveTabs() { bool TabStrip::ShouldHideCloseButtonForTab(Tab* tab) const {
if (tab->IsActive())
return SingleTabMode();
return touch_layout_ != nullptr || MD::IsRefreshUi(); return touch_layout_ != nullptr || MD::IsRefreshUi();
} }
...@@ -2406,6 +2420,12 @@ void TabStrip::SetResetToShrinkOnExit(bool value) { ...@@ -2406,6 +2420,12 @@ void TabStrip::SetResetToShrinkOnExit(bool value) {
RemoveMessageLoopObserver(); RemoveMessageLoopObserver();
} }
void TabStrip::SingleTabModeChanged() {
const int active_tab_index = controller_->GetActiveIndex();
if (IsValidModelIndex(active_tab_index))
tab_at(active_tab_index)->Layout();
}
void TabStrip::ButtonPressed(views::Button* sender, const ui::Event& event) { void TabStrip::ButtonPressed(views::Button* sender, const ui::Event& event) {
if (sender == new_tab_button_) { if (sender == new_tab_button_) {
base::RecordAction(UserMetricsAction("NewTab_Button")); base::RecordAction(UserMetricsAction("NewTab_Button"));
......
...@@ -124,6 +124,13 @@ class TabStrip : public views::View, ...@@ -124,6 +124,13 @@ class TabStrip : public views::View,
// Sets |stacked_layout_| and animates if necessary. // Sets |stacked_layout_| and animates if necessary.
void SetStackedLayout(bool stacked_layout); void SetStackedLayout(bool stacked_layout);
// Whether the special painting mode for a single tab is enabled. This is only
// true if both the mode is available and we have exactly one tab.
bool SingleTabMode() const;
// Called when the value of SingleTabMode() changes.
void SingleTabModeChanged();
// Returns the bounds of the new tab button. // Returns the bounds of the new tab button.
gfx::Rect new_tab_button_bounds() const { return new_tab_button_bounds_; } gfx::Rect new_tab_button_bounds() const { return new_tab_button_bounds_; }
...@@ -219,7 +226,7 @@ class TabStrip : public views::View, ...@@ -219,7 +226,7 @@ class TabStrip : public views::View,
// TabController overrides: // TabController overrides:
const ui::ListSelectionModel& GetSelectionModel() const override; const ui::ListSelectionModel& GetSelectionModel() const override;
bool SupportsMultipleSelection() override; bool SupportsMultipleSelection() override;
bool ShouldHideCloseButtonForInactiveTabs() override; bool ShouldHideCloseButtonForTab(Tab* tab) const override;
bool ShouldShowCloseButtonOnHover() override; bool ShouldShowCloseButtonOnHover() override;
bool MaySetClip() override; bool MaySetClip() override;
void SelectTab(Tab* tab) override; void SelectTab(Tab* tab) override;
......
...@@ -102,6 +102,9 @@ class TabStripController { ...@@ -102,6 +102,9 @@ class TabStripController {
// Invoked if the stacked layout (on or off) might have changed. // Invoked if the stacked layout (on or off) might have changed.
virtual void StackedLayoutMaybeChanged() = 0; virtual void StackedLayoutMaybeChanged() = 0;
// Whether the special painting mode for one tab is allowed.
virtual bool IsSingleTabModeAvailable() = 0;
// Notifies controller that the user started dragging this tabstrip's tabs. // Notifies controller that the user started dragging this tabstrip's tabs.
virtual void OnStartedDraggingTabs() = 0; virtual void OnStartedDraggingTabs() = 0;
......
...@@ -38,9 +38,7 @@ class FakeTabController : public TabController { ...@@ -38,9 +38,7 @@ class FakeTabController : public TabController {
return selection_model_; return selection_model_;
} }
bool SupportsMultipleSelection() override { return false; } bool SupportsMultipleSelection() override { return false; }
bool ShouldHideCloseButtonForInactiveTabs() override { bool ShouldHideCloseButtonForTab(Tab* tab) const override { return false; }
return false;
}
bool ShouldShowCloseButtonOnHover() override { return false; } bool ShouldShowCloseButtonOnHover() override { return false; }
bool MaySetClip() override { return false; } bool MaySetClip() override { return false; }
void SelectTab(Tab* tab) override {} void SelectTab(Tab* tab) override {}
......
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