Index: chrome/browser/ui/views/tabs/tab_unittest.cc |
diff --git a/chrome/browser/ui/views/tabs/tab_unittest.cc b/chrome/browser/ui/views/tabs/tab_unittest.cc |
index 23d564d07c08569f8d79f152fce868cedcd93685..ebdada63723f68919f4e13b7381e618150d17cca 100644 |
--- a/chrome/browser/ui/views/tabs/tab_unittest.cc |
+++ b/chrome/browser/ui/views/tabs/tab_unittest.cc |
@@ -1,296 +1,299 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/ui/views/tabs/tab.h" |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/ui/views/tabs/tab.h" |
+ |
+#include "base/strings/utf_string_conversions.h" |
#include "chrome/browser/ui/views/tabs/tab_controller.h" |
- |
-#include "base/strings/utf_string_conversions.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
-#include "ui/base/models/list_selection_model.h" |
-#include "ui/views/controls/button/image_button.h" |
-#include "ui/views/test/views_test_base.h" |
-#include "ui/views/widget/widget.h" |
- |
-using views::Widget; |
- |
-class FakeTabController : public TabController { |
- public: |
- FakeTabController() : immersive_style_(false), active_tab_(false) { |
- } |
- virtual ~FakeTabController() {} |
- |
- void set_immersive_style(bool value) { immersive_style_ = value; } |
- void set_active_tab(bool value) { active_tab_ = value; } |
- |
- virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE { |
- return selection_model_; |
- } |
- virtual bool SupportsMultipleSelection() OVERRIDE { return false; } |
- virtual void SelectTab(Tab* tab) OVERRIDE {} |
- virtual void ExtendSelectionTo(Tab* tab) OVERRIDE {} |
- virtual void ToggleSelected(Tab* tab) OVERRIDE {} |
- virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE {} |
- virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE {} |
- virtual void ShowContextMenuForTab(Tab* tab, |
- const gfx::Point& p, |
- ui::MenuSourceType source_type) OVERRIDE {} |
- virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { |
- return active_tab_; |
- } |
- virtual bool IsTabSelected(const Tab* tab) const OVERRIDE { |
- return false; |
- } |
- virtual bool IsTabPinned(const Tab* tab) const OVERRIDE { return false; } |
- virtual void MaybeStartDrag( |
- Tab* tab, |
- const ui::LocatedEvent& event, |
- const ui::ListSelectionModel& original_selection) OVERRIDE {} |
- virtual void ContinueDrag(views::View* view, |
- const ui::LocatedEvent& event) OVERRIDE {} |
- virtual bool EndDrag(EndDragReason reason) OVERRIDE { return false; } |
- virtual Tab* GetTabAt(Tab* tab, |
- const gfx::Point& tab_in_tab_coordinates) OVERRIDE { |
- return NULL; |
- } |
- virtual void OnMouseEventInTab(views::View* source, |
- const ui::MouseEvent& event) OVERRIDE {} |
- virtual bool ShouldPaintTab(const Tab* tab, gfx::Rect* clip) OVERRIDE { |
- return true; |
- } |
- virtual bool IsImmersiveStyle() const OVERRIDE { return immersive_style_; } |
- |
- private: |
- ui::ListSelectionModel selection_model_; |
- bool immersive_style_; |
- bool active_tab_; |
- |
- DISALLOW_COPY_AND_ASSIGN(FakeTabController); |
-}; |
- |
-class TabTest : public views::ViewsTestBase { |
- public: |
- TabTest() {} |
- virtual ~TabTest() {} |
- |
- static void DisableMediaIndicatorAnimation(Tab* tab) { |
- tab->media_indicator_animation_.reset(); |
- tab->animating_media_state_ = tab->data_.media_state; |
- } |
- |
- static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { |
- // Check whether elements are visible when they are supposed to be, given |
- // Tab size and TabRendererData state. |
- if (tab.data_.mini) { |
- EXPECT_EQ(1, tab.IconCapacity()); |
- if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
- EXPECT_FALSE(tab.ShouldShowIcon()); |
- EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
- } else { |
- EXPECT_TRUE(tab.ShouldShowIcon()); |
- EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
- } |
- EXPECT_FALSE(tab.ShouldShowCloseBox()); |
- } else if (tab.IsActive()) { |
- EXPECT_TRUE(tab.ShouldShowCloseBox()); |
- switch (tab.IconCapacity()) { |
- case 0: |
- case 1: |
- EXPECT_FALSE(tab.ShouldShowIcon()); |
- EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
- break; |
- case 2: |
- if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
- EXPECT_FALSE(tab.ShouldShowIcon()); |
- EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
- } else { |
- EXPECT_TRUE(tab.ShouldShowIcon()); |
- EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
- } |
- break; |
- default: |
- EXPECT_LE(3, tab.IconCapacity()); |
- EXPECT_TRUE(tab.ShouldShowIcon()); |
- if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) |
- EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
- else |
- EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
- break; |
- } |
- } else { // Tab not active and not mini tab. |
- switch (tab.IconCapacity()) { |
- case 0: |
- EXPECT_FALSE(tab.ShouldShowCloseBox()); |
- EXPECT_FALSE(tab.ShouldShowIcon()); |
- EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
- break; |
- case 1: |
- EXPECT_FALSE(tab.ShouldShowCloseBox()); |
- if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
- EXPECT_FALSE(tab.ShouldShowIcon()); |
- EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
- } else { |
- EXPECT_TRUE(tab.ShouldShowIcon()); |
- EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
- } |
- break; |
- default: |
- EXPECT_LE(2, tab.IconCapacity()); |
- EXPECT_TRUE(tab.ShouldShowIcon()); |
- if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) |
- EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
- else |
- EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
- break; |
- } |
- } |
- |
- // Check positioning of elements with respect to each other, and that they |
- // are fully within the contents bounds. |
- const gfx::Rect contents_bounds = tab.GetContentsBounds(); |
- if (tab.ShouldShowIcon()) { |
- EXPECT_LE(contents_bounds.x(), tab.favicon_bounds_.x()); |
- if (tab.title_bounds_.width() > 0) |
- EXPECT_LE(tab.favicon_bounds_.right(), tab.title_bounds_.x()); |
- EXPECT_LE(contents_bounds.y(), tab.favicon_bounds_.y()); |
- EXPECT_LE(tab.favicon_bounds_.bottom(), contents_bounds.bottom()); |
- } |
- if (tab.ShouldShowIcon() && tab.ShouldShowMediaIndicator()) |
- EXPECT_LE(tab.favicon_bounds_.right(), tab.media_indicator_bounds_.x()); |
- if (tab.ShouldShowMediaIndicator()) { |
- if (tab.title_bounds_.width() > 0) |
- EXPECT_LE(tab.title_bounds_.right(), tab.media_indicator_bounds_.x()); |
- EXPECT_LE(tab.media_indicator_bounds_.right(), contents_bounds.right()); |
- EXPECT_LE(contents_bounds.y(), tab.media_indicator_bounds_.y()); |
- EXPECT_LE(tab.media_indicator_bounds_.bottom(), contents_bounds.bottom()); |
- } |
- if (tab.ShouldShowMediaIndicator() && tab.ShouldShowCloseBox()) { |
- // Note: The media indicator can overlap the left-insets of the close box, |
- // but should otherwise be to the left of the close button. |
- EXPECT_LE(tab.media_indicator_bounds_.right(), |
- tab.close_button_->bounds().x() + |
- tab.close_button_->GetInsets().left()); |
- } |
- if (tab.ShouldShowCloseBox()) { |
- // Note: The title bounds can overlap the left-insets of the close box, |
- // but should otherwise be to the left of the close button. |
- if (tab.title_bounds_.width() > 0) { |
- EXPECT_LE(tab.title_bounds_.right(), |
- tab.close_button_->bounds().x() + |
- tab.close_button_->GetInsets().left()); |
- } |
- EXPECT_LE(tab.close_button_->bounds().right(), contents_bounds.right()); |
- EXPECT_LE(contents_bounds.y(), tab.close_button_->bounds().y()); |
- EXPECT_LE(tab.close_button_->bounds().bottom(), contents_bounds.bottom()); |
- } |
- } |
-}; |
- |
-TEST_F(TabTest, HitTestTopPixel) { |
- Widget widget; |
- Widget::InitParams params(CreateParams(Widget::InitParams::TYPE_WINDOW)); |
- params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
- params.bounds.SetRect(10, 20, 300, 400); |
- widget.Init(params); |
- |
- FakeTabController tab_controller; |
- Tab tab(&tab_controller); |
- widget.GetContentsView()->AddChildView(&tab); |
- tab.SetBoundsRect(gfx::Rect(gfx::Point(0, 0), Tab::GetStandardSize())); |
- |
- // Tabs have some shadow in the top, so by default we don't hit the tab there. |
- int middle_x = tab.width() / 2; |
- EXPECT_FALSE(tab.HitTestPoint(gfx::Point(middle_x, 0))); |
- |
- // Tabs are slanted, so a click halfway down the left edge won't hit it. |
- int middle_y = tab.height() / 2; |
- EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, middle_y))); |
- |
- // If the window is maximized, however, we want clicks in the top edge to |
- // select the tab. |
- widget.Maximize(); |
- EXPECT_TRUE(tab.HitTestPoint(gfx::Point(middle_x, 0))); |
- |
- // But clicks in the area above the slanted sides should still miss. |
- EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, 0))); |
- EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0))); |
-} |
- |
-TEST_F(TabTest, LayoutAndVisibilityOfElements) { |
- static const TabMediaState kMediaStatesToTest[] = { |
- TAB_MEDIA_STATE_NONE, TAB_MEDIA_STATE_CAPTURING, |
- TAB_MEDIA_STATE_AUDIO_PLAYING |
- }; |
- |
- FakeTabController controller; |
- Tab tab(&controller); |
- |
- SkBitmap bitmap; |
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); |
- bitmap.allocPixels(); |
- TabRendererData data; |
- data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
- |
- // Perform layout over all possible combinations, checking for correct |
- // results. |
- for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) { |
- for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) { |
- for (size_t media_state_index = 0; |
- media_state_index < arraysize(kMediaStatesToTest); |
- ++media_state_index) { |
- const TabMediaState media_state = kMediaStatesToTest[media_state_index]; |
- SCOPED_TRACE(::testing::Message() |
- << (is_active_tab ? "Active" : "Inactive") << ' ' |
- << (is_mini_tab ? "Mini " : "") |
- << "Tab with media indicator state " << media_state); |
- |
- data.mini = !!is_mini_tab; |
- controller.set_active_tab(!!is_active_tab); |
- data.media_state = media_state; |
- tab.SetData(data); |
- |
- // Disable the media indicator animation so that the layout/visibility |
- // logic can be tested effectively. If the animation was left enabled, |
- // the ShouldShowMediaIndicator() method would return true during |
- // fade-out transitions. |
- DisableMediaIndicatorAnimation(&tab); |
- |
- // Test layout for every width from standard to minimum. |
- gfx::Rect bounds(gfx::Point(0, 0), Tab::GetStandardSize()); |
- int min_width; |
- if (is_mini_tab) { |
- bounds.set_width(Tab::GetMiniWidth()); |
- min_width = Tab::GetMiniWidth(); |
- } else { |
- min_width = is_active_tab ? Tab::GetMinimumSelectedSize().width() : |
- Tab::GetMinimumUnselectedSize().width(); |
- } |
- while (bounds.width() >= min_width) { |
- SCOPED_TRACE(::testing::Message() << "bounds=" << bounds.ToString()); |
- tab.SetBoundsRect(bounds); // Invokes Tab::Layout(). |
- CheckForExpectedLayoutAndVisibilityOfElements(tab); |
- bounds.set_width(bounds.width() - 1); |
- } |
- } |
- } |
- } |
-} |
- |
-// Regression test for http://crbug.com/226253. Calling Layout() more than once |
-// shouldn't change the insets of the close button. |
-TEST_F(TabTest, CloseButtonLayout) { |
- FakeTabController tab_controller; |
- Tab tab(&tab_controller); |
- tab.SetBounds(0, 0, 100, 50); |
- tab.Layout(); |
- gfx::Insets close_button_insets = tab.close_button_->GetInsets(); |
- tab.Layout(); |
- gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets(); |
- EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); |
- EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); |
- EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); |
- EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); |
- |
- // Also make sure the close button is sized as large as the tab. |
- EXPECT_EQ(50, tab.close_button_->bounds().height()); |
-} |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "ui/base/models/list_selection_model.h" |
+#include "ui/views/controls/button/image_button.h" |
+#include "ui/views/controls/label.h" |
+#include "ui/views/test/views_test_base.h" |
+#include "ui/views/widget/widget.h" |
+ |
+using views::Widget; |
+ |
+class FakeTabController : public TabController { |
+ public: |
+ FakeTabController() : immersive_style_(false), active_tab_(false) { |
+ } |
+ virtual ~FakeTabController() {} |
+ |
+ void set_immersive_style(bool value) { immersive_style_ = value; } |
+ void set_active_tab(bool value) { active_tab_ = value; } |
+ |
+ virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE { |
+ return selection_model_; |
+ } |
+ virtual bool SupportsMultipleSelection() OVERRIDE { return false; } |
+ virtual void SelectTab(Tab* tab) OVERRIDE {} |
+ virtual void ExtendSelectionTo(Tab* tab) OVERRIDE {} |
+ virtual void ToggleSelected(Tab* tab) OVERRIDE {} |
+ virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE {} |
+ virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE {} |
+ virtual void ShowContextMenuForTab(Tab* tab, |
+ const gfx::Point& p, |
+ ui::MenuSourceType source_type) OVERRIDE {} |
+ virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { |
+ return active_tab_; |
+ } |
+ virtual bool IsTabSelected(const Tab* tab) const OVERRIDE { |
+ return false; |
+ } |
+ virtual bool IsTabPinned(const Tab* tab) const OVERRIDE { return false; } |
+ virtual void MaybeStartDrag( |
+ Tab* tab, |
+ const ui::LocatedEvent& event, |
+ const ui::ListSelectionModel& original_selection) OVERRIDE {} |
+ virtual void ContinueDrag(views::View* view, |
+ const ui::LocatedEvent& event) OVERRIDE {} |
+ virtual bool EndDrag(EndDragReason reason) OVERRIDE { return false; } |
+ virtual Tab* GetTabAt(Tab* tab, |
+ const gfx::Point& tab_in_tab_coordinates) OVERRIDE { |
+ return NULL; |
+ } |
+ virtual void OnMouseEventInTab(views::View* source, |
+ const ui::MouseEvent& event) OVERRIDE {} |
+ virtual bool ShouldPaintTab(const Tab* tab, gfx::Rect* clip) OVERRIDE { |
+ return true; |
+ } |
+ virtual bool IsImmersiveStyle() const OVERRIDE { return immersive_style_; } |
+ |
+ private: |
+ ui::ListSelectionModel selection_model_; |
+ bool immersive_style_; |
+ bool active_tab_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FakeTabController); |
+}; |
+ |
+class TabTest : public views::ViewsTestBase { |
+ public: |
+ TabTest() {} |
+ virtual ~TabTest() {} |
+ |
+ static void DisableMediaIndicatorAnimation(Tab* tab) { |
+ tab->media_indicator_animation_.reset(); |
+ tab->animating_media_state_ = tab->data_.media_state; |
+ } |
+ |
+ static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { |
+ // Check whether elements are visible when they are supposed to be, given |
+ // Tab size and TabRendererData state. |
+ if (tab.data_.mini) { |
+ EXPECT_EQ(1, tab.IconCapacity()); |
+ if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
+ EXPECT_FALSE(tab.ShouldShowIcon()); |
+ EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
+ } else { |
+ EXPECT_TRUE(tab.ShouldShowIcon()); |
+ EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
+ } |
+ EXPECT_FALSE(tab.ShouldShowCloseBox()); |
+ } else if (tab.IsActive()) { |
+ EXPECT_TRUE(tab.ShouldShowCloseBox()); |
+ switch (tab.IconCapacity()) { |
+ case 0: |
+ case 1: |
+ EXPECT_FALSE(tab.ShouldShowIcon()); |
+ EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
+ break; |
+ case 2: |
+ if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
+ EXPECT_FALSE(tab.ShouldShowIcon()); |
+ EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
+ } else { |
+ EXPECT_TRUE(tab.ShouldShowIcon()); |
+ EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
+ } |
+ break; |
+ default: |
+ EXPECT_LE(3, tab.IconCapacity()); |
+ EXPECT_TRUE(tab.ShouldShowIcon()); |
+ if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) |
+ EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
+ else |
+ EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
+ break; |
+ } |
+ } else { // Tab not active and not mini tab. |
+ switch (tab.IconCapacity()) { |
+ case 0: |
+ EXPECT_FALSE(tab.ShouldShowCloseBox()); |
+ EXPECT_FALSE(tab.ShouldShowIcon()); |
+ EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
+ break; |
+ case 1: |
+ EXPECT_FALSE(tab.ShouldShowCloseBox()); |
+ if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
+ EXPECT_FALSE(tab.ShouldShowIcon()); |
+ EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
+ } else { |
+ EXPECT_TRUE(tab.ShouldShowIcon()); |
+ EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
+ } |
+ break; |
+ default: |
+ EXPECT_LE(2, tab.IconCapacity()); |
+ EXPECT_TRUE(tab.ShouldShowIcon()); |
+ if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) |
+ EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
+ else |
+ EXPECT_FALSE(tab.ShouldShowMediaIndicator()); |
+ break; |
+ } |
+ } |
+ |
+ // Check positioning of elements with respect to each other, and that they |
+ // are fully within the contents bounds. |
+ const gfx::Rect contents_bounds = tab.GetContentsBounds(); |
+ if (tab.ShouldShowIcon()) { |
+ EXPECT_LE(contents_bounds.x(), tab.favicon_bounds_.x()); |
+ if (tab.title_->width() > 0) |
+ EXPECT_LE(tab.favicon_bounds_.right(), tab.title_->x()); |
+ EXPECT_LE(contents_bounds.y(), tab.favicon_bounds_.y()); |
+ EXPECT_LE(tab.favicon_bounds_.bottom(), contents_bounds.bottom()); |
+ } |
+ if (tab.ShouldShowIcon() && tab.ShouldShowMediaIndicator()) |
+ EXPECT_LE(tab.favicon_bounds_.right(), tab.media_indicator_bounds_.x()); |
+ if (tab.ShouldShowMediaIndicator()) { |
+ if (tab.title_->width() > 0) { |
+ EXPECT_LE(tab.title_->bounds().right(), |
+ tab.media_indicator_bounds_.x()); |
+ } |
+ EXPECT_LE(tab.media_indicator_bounds_.right(), contents_bounds.right()); |
+ EXPECT_LE(contents_bounds.y(), tab.media_indicator_bounds_.y()); |
+ EXPECT_LE(tab.media_indicator_bounds_.bottom(), contents_bounds.bottom()); |
+ } |
+ if (tab.ShouldShowMediaIndicator() && tab.ShouldShowCloseBox()) { |
+ // Note: The media indicator can overlap the left-insets of the close box, |
+ // but should otherwise be to the left of the close button. |
+ EXPECT_LE(tab.media_indicator_bounds_.right(), |
+ tab.close_button_->bounds().x() + |
+ tab.close_button_->GetInsets().left()); |
+ } |
+ if (tab.ShouldShowCloseBox()) { |
+ // Note: The title bounds can overlap the left-insets of the close box, |
+ // but should otherwise be to the left of the close button. |
+ if (tab.title_->width() > 0) { |
+ EXPECT_LE(tab.title_->bounds().right(), |
+ tab.close_button_->bounds().x() + |
+ tab.close_button_->GetInsets().left()); |
+ } |
+ EXPECT_LE(tab.close_button_->bounds().right(), contents_bounds.right()); |
+ EXPECT_LE(contents_bounds.y(), tab.close_button_->bounds().y()); |
+ EXPECT_LE(tab.close_button_->bounds().bottom(), contents_bounds.bottom()); |
+ } |
+ } |
+}; |
+ |
+TEST_F(TabTest, HitTestTopPixel) { |
+ Widget widget; |
+ Widget::InitParams params(CreateParams(Widget::InitParams::TYPE_WINDOW)); |
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
+ params.bounds.SetRect(10, 20, 300, 400); |
+ widget.Init(params); |
+ |
+ FakeTabController tab_controller; |
+ Tab tab(&tab_controller); |
+ widget.GetContentsView()->AddChildView(&tab); |
+ tab.SetBoundsRect(gfx::Rect(gfx::Point(0, 0), Tab::GetStandardSize())); |
+ |
+ // Tabs have some shadow in the top, so by default we don't hit the tab there. |
+ int middle_x = tab.width() / 2; |
+ EXPECT_FALSE(tab.HitTestPoint(gfx::Point(middle_x, 0))); |
+ |
+ // Tabs are slanted, so a click halfway down the left edge won't hit it. |
+ int middle_y = tab.height() / 2; |
+ EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, middle_y))); |
+ |
+ // If the window is maximized, however, we want clicks in the top edge to |
+ // select the tab. |
+ widget.Maximize(); |
+ EXPECT_TRUE(tab.HitTestPoint(gfx::Point(middle_x, 0))); |
+ |
+ // But clicks in the area above the slanted sides should still miss. |
+ EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, 0))); |
+ EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0))); |
+} |
+ |
+TEST_F(TabTest, LayoutAndVisibilityOfElements) { |
+ static const TabMediaState kMediaStatesToTest[] = { |
+ TAB_MEDIA_STATE_NONE, TAB_MEDIA_STATE_CAPTURING, |
+ TAB_MEDIA_STATE_AUDIO_PLAYING |
+ }; |
+ |
+ FakeTabController controller; |
+ Tab tab(&controller); |
+ |
+ SkBitmap bitmap; |
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16); |
+ bitmap.allocPixels(); |
+ TabRendererData data; |
+ data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
+ |
+ // Perform layout over all possible combinations, checking for correct |
+ // results. |
+ for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) { |
+ for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) { |
+ for (size_t media_state_index = 0; |
+ media_state_index < arraysize(kMediaStatesToTest); |
+ ++media_state_index) { |
+ const TabMediaState media_state = kMediaStatesToTest[media_state_index]; |
+ SCOPED_TRACE(::testing::Message() |
+ << (is_active_tab ? "Active" : "Inactive") << ' ' |
+ << (is_mini_tab ? "Mini " : "") |
+ << "Tab with media indicator state " << media_state); |
+ |
+ data.mini = !!is_mini_tab; |
+ controller.set_active_tab(!!is_active_tab); |
+ data.media_state = media_state; |
+ tab.SetData(data); |
+ |
+ // Disable the media indicator animation so that the layout/visibility |
+ // logic can be tested effectively. If the animation was left enabled, |
+ // the ShouldShowMediaIndicator() method would return true during |
+ // fade-out transitions. |
+ DisableMediaIndicatorAnimation(&tab); |
+ |
+ // Test layout for every width from standard to minimum. |
+ gfx::Rect bounds(gfx::Point(0, 0), Tab::GetStandardSize()); |
+ int min_width; |
+ if (is_mini_tab) { |
+ bounds.set_width(Tab::GetMiniWidth()); |
+ min_width = Tab::GetMiniWidth(); |
+ } else { |
+ min_width = is_active_tab ? Tab::GetMinimumSelectedSize().width() : |
+ Tab::GetMinimumUnselectedSize().width(); |
+ } |
+ while (bounds.width() >= min_width) { |
+ SCOPED_TRACE(::testing::Message() << "bounds=" << bounds.ToString()); |
+ tab.SetBoundsRect(bounds); // Invokes Tab::Layout(). |
+ CheckForExpectedLayoutAndVisibilityOfElements(tab); |
+ bounds.set_width(bounds.width() - 1); |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+// Regression test for http://crbug.com/226253. Calling Layout() more than once |
+// shouldn't change the insets of the close button. |
+TEST_F(TabTest, CloseButtonLayout) { |
+ FakeTabController tab_controller; |
+ Tab tab(&tab_controller); |
+ tab.SetBounds(0, 0, 100, 50); |
+ tab.Layout(); |
+ gfx::Insets close_button_insets = tab.close_button_->GetInsets(); |
+ tab.Layout(); |
+ gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets(); |
+ EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); |
+ EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); |
+ EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); |
+ EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); |
+ |
+ // Also make sure the close button is sized as large as the tab. |
+ EXPECT_EQ(50, tab.close_button_->bounds().height()); |
+} |