OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h" | 5 #include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/ui/layout_constants.h" |
10 #include "chrome/browser/ui/views/profiles/avatar_menu_button.h" | 11 #include "chrome/browser/ui/views/profiles/avatar_menu_button.h" |
11 #include "chrome/browser/ui/views/tab_icon_view.h" | 12 #include "chrome/browser/ui/views/tab_icon_view.h" |
12 #include "chrome/browser/ui/views/tabs/tab.h" | 13 #include "chrome/browser/ui/views/tabs/tab.h" |
13 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
14 #include "components/signin/core/common/profile_management_switches.h" | 15 #include "components/signin/core/common/profile_management_switches.h" |
15 #include "ui/gfx/image/image_skia.h" | 16 #include "ui/gfx/image/image_skia.h" |
16 #include "ui/gfx/image/image_skia_rep.h" | 17 #include "ui/gfx/image/image_skia_rep.h" |
17 #include "ui/gfx/text_constants.h" | 18 #include "ui/gfx/text_constants.h" |
18 #include "ui/views/controls/button/image_button.h" | 19 #include "ui/views/controls/button/image_button.h" |
19 #include "ui/views/controls/button/menu_button.h" | 20 #include "ui/views/controls/button/menu_button.h" |
20 #include "ui/views/controls/label.h" | 21 #include "ui/views/controls/label.h" |
21 #include "ui/views/test/views_test_base.h" | 22 #include "ui/views/test/views_test_base.h" |
22 | 23 |
23 using views::Widget; | 24 using OBFVL = OpaqueBrowserFrameViewLayout; |
24 | 25 |
25 namespace { | 26 namespace { |
26 | 27 |
27 const int kWidth = 500; | 28 const int kWindowWidth = 500; |
| 29 const int kNonClientBorderThickness = OBFVL::kFrameBorderThickness + |
| 30 views::NonClientFrameView::kClientEdgeThickness; |
| 31 const int kMinimizeButtonWidth = 26; |
| 32 const int kMaximizeButtonWidth = 25; |
| 33 const int kCloseButtonWidth = 43; |
| 34 const int kMaximizedExtraCloseWidth = OBFVL::kFrameBorderThickness - |
| 35 views::NonClientFrameView::kFrameShadowThickness; |
| 36 const int kCaptionButtonsWidth = |
| 37 kMinimizeButtonWidth + kMaximizeButtonWidth + kCloseButtonWidth; |
| 38 const int kCaptionButtonHeight = 18; |
28 | 39 |
29 class TestLayoutDelegate : public OpaqueBrowserFrameViewLayoutDelegate { | 40 class TestLayoutDelegate : public OpaqueBrowserFrameViewLayoutDelegate { |
30 public: | 41 public: |
31 enum WindowState { | |
32 STATE_NORMAL, | |
33 STATE_MAXIMIZED, | |
34 STATE_MINIMIZED, | |
35 STATE_FULLSCREEN | |
36 }; | |
37 | |
38 TestLayoutDelegate() | 42 TestLayoutDelegate() |
39 : show_avatar_(false), | 43 : show_avatar_(false), |
40 show_caption_buttons_(true), | 44 show_caption_buttons_(true), |
41 window_state_(STATE_NORMAL) { | 45 maximized_(false) { |
42 } | 46 } |
43 | |
44 ~TestLayoutDelegate() override {} | 47 ~TestLayoutDelegate() override {} |
45 | 48 |
46 void SetWindowTitle(const base::string16& title) { | 49 void set_window_title(const base::string16& title) { window_title_ = title; } |
47 window_title_ = title; | 50 void set_show_avatar(bool show_avatar) { show_avatar_ = show_avatar; } |
48 } | 51 void set_show_caption_buttons(bool show_caption_buttons) { |
49 | |
50 void SetShouldShowAvatar(bool show_avatar) { | |
51 show_avatar_ = show_avatar; | |
52 } | |
53 | |
54 void SetShouldShowCaptionButtons(bool show_caption_buttons) { | |
55 show_caption_buttons_ = show_caption_buttons; | 52 show_caption_buttons_ = show_caption_buttons; |
56 } | 53 } |
| 54 void set_maximized(bool maximized) { maximized_ = maximized; } |
57 | 55 |
58 void SetWindowState(WindowState state) { | 56 // OpaqueBrowserFrameViewLayoutDelegate: |
59 window_state_ = state; | |
60 } | |
61 | |
62 // OpaqueBrowserFrameViewLayoutDelegate overrides: | |
63 | |
64 bool ShouldShowWindowIcon() const override { return !window_title_.empty(); } | 57 bool ShouldShowWindowIcon() const override { return !window_title_.empty(); } |
65 | |
66 bool ShouldShowWindowTitle() const override { return !window_title_.empty(); } | 58 bool ShouldShowWindowTitle() const override { return !window_title_.empty(); } |
67 | |
68 base::string16 GetWindowTitle() const override { return window_title_; } | 59 base::string16 GetWindowTitle() const override { return window_title_; } |
69 | 60 int GetIconSize() const override { return 17; } |
70 int GetIconSize() const override { | |
71 // The value on linux_aura and non-aura windows. | |
72 return 17; | |
73 } | |
74 | |
75 gfx::Size GetBrowserViewMinimumSize() const override { | 61 gfx::Size GetBrowserViewMinimumSize() const override { |
76 // Taken from a calculation in BrowserViewLayout. | |
77 return gfx::Size(168, 64); | 62 return gfx::Size(168, 64); |
78 } | 63 } |
79 | |
80 bool ShouldShowCaptionButtons() const override { | 64 bool ShouldShowCaptionButtons() const override { |
81 return show_caption_buttons_; | 65 return show_caption_buttons_; |
82 } | 66 } |
83 | |
84 bool ShouldShowAvatar() const override { return show_avatar_; } | 67 bool ShouldShowAvatar() const override { return show_avatar_; } |
85 | |
86 bool IsRegularOrGuestSession() const override { return true; } | 68 bool IsRegularOrGuestSession() const override { return true; } |
87 | |
88 gfx::ImageSkia GetOTRAvatarIcon() const override { | 69 gfx::ImageSkia GetOTRAvatarIcon() const override { |
89 // The calculations depend on the size of the OTR resource, and chromeos | 70 return gfx::ImageSkia(gfx::ImageSkiaRep(gfx::Size(40, 29), 1.0f)); |
90 // uses a different sized image, so hard code the size of the current | |
91 // windows/linux one. | |
92 gfx::ImageSkiaRep rep(gfx::Size(40, 29), 1.0f); | |
93 gfx::ImageSkia image(rep); | |
94 return image; | |
95 } | 71 } |
96 | 72 bool IsMaximized() const override { return maximized_; } |
97 bool IsMaximized() const override { return window_state_ == STATE_MAXIMIZED; } | 73 bool IsMinimized() const override { return false; } |
98 | 74 bool IsFullscreen() const override { return false; } |
99 bool IsMinimized() const override { return window_state_ == STATE_MINIMIZED; } | |
100 | |
101 bool IsFullscreen() const override { | |
102 return window_state_ == STATE_FULLSCREEN; | |
103 } | |
104 | |
105 bool IsTabStripVisible() const override { return window_title_.empty(); } | 75 bool IsTabStripVisible() const override { return window_title_.empty(); } |
106 | |
107 int GetTabStripHeight() const override { | 76 int GetTabStripHeight() const override { |
108 return IsTabStripVisible() ? Tab::GetMinimumInactiveSize().height() : 0; | 77 return IsTabStripVisible() ? Tab::GetMinimumInactiveSize().height() : 0; |
109 } | 78 } |
110 | |
111 bool IsToolbarVisible() const override { return true; } | 79 bool IsToolbarVisible() const override { return true; } |
112 | |
113 gfx::Size GetTabstripPreferredSize() const override { | 80 gfx::Size GetTabstripPreferredSize() const override { |
114 // Measured from Tabstrip::GetPreferredSize(). | 81 return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(); |
115 return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(0, 0); | |
116 } | 82 } |
117 | 83 int GetToolbarLeadingCornerClientWidth() const override { return 0; } |
118 int GetToolbarLeadingCornerClientWidth() const override { | |
119 return 0; | |
120 } | |
121 | 84 |
122 private: | 85 private: |
123 base::string16 window_title_; | 86 base::string16 window_title_; |
124 bool show_avatar_; | 87 bool show_avatar_; |
125 bool show_caption_buttons_; | 88 bool show_caption_buttons_; |
126 WindowState window_state_; | 89 bool maximized_; |
127 | 90 |
128 DISALLOW_COPY_AND_ASSIGN(TestLayoutDelegate); | 91 DISALLOW_COPY_AND_ASSIGN(TestLayoutDelegate); |
129 }; | 92 }; |
130 | 93 |
131 } // namespace | 94 } // namespace |
132 | 95 |
133 class OpaqueBrowserFrameViewLayoutTest : public views::ViewsTestBase { | 96 class OpaqueBrowserFrameViewLayoutTest : public views::ViewsTestBase { |
134 public: | 97 public: |
135 OpaqueBrowserFrameViewLayoutTest() {} | 98 OpaqueBrowserFrameViewLayoutTest() {} |
136 ~OpaqueBrowserFrameViewLayoutTest() override {} | 99 ~OpaqueBrowserFrameViewLayoutTest() override {} |
137 | 100 |
138 void SetUp() override { | 101 void SetUp() override { |
139 views::ViewsTestBase::SetUp(); | 102 views::ViewsTestBase::SetUp(); |
140 | 103 |
141 delegate_.reset(new TestLayoutDelegate); | 104 delegate_.reset(new TestLayoutDelegate); |
142 layout_manager_ = new OpaqueBrowserFrameViewLayout(delegate_.get()); | 105 layout_manager_ = new OBFVL(delegate_.get()); |
143 layout_manager_->set_extra_caption_y(0); | 106 layout_manager_->set_extra_caption_y(0); |
144 layout_manager_->set_window_caption_spacing(0); | 107 layout_manager_->set_window_caption_spacing(0); |
145 widget_ = new Widget; | 108 widget_ = new views::Widget; |
146 widget_->Init(CreateParams(Widget::InitParams::TYPE_POPUP)); | 109 widget_->Init(CreateParams(views::Widget::InitParams::TYPE_POPUP)); |
147 root_view_ = widget_->GetRootView(); | 110 root_view_ = widget_->GetRootView(); |
148 root_view_->SetSize(gfx::Size(kWidth, kWidth)); | 111 root_view_->SetSize(gfx::Size(kWindowWidth, kWindowWidth)); |
149 root_view_->SetLayoutManager(layout_manager_); | 112 root_view_->SetLayoutManager(layout_manager_); |
150 | 113 |
151 // Add the caption buttons. We use fake images because we're modeling the | 114 // Add the caption buttons. We use fake images because we're modeling the |
152 // Windows assets here, while the linux version uses differently sized | 115 // Windows assets here, while the linux version uses differently sized |
153 // assets. | 116 // assets. |
154 // | 117 // |
155 // TODO(erg): In a follow up patch, separate these sizes out into virtual | 118 // TODO(erg): In a follow up patch, separate these sizes out into virtual |
156 // accessors so we can test both the windows and linux behaviours once we | 119 // accessors so we can test both the windows and linux behaviours once we |
157 // start modifying the code. | 120 // start modifying the code. |
158 minimize_button_ = InitWindowCaptionButton( | 121 minimize_button_ = InitWindowCaptionButton( |
159 VIEW_ID_MINIMIZE_BUTTON, gfx::Size(26, 18)); | 122 VIEW_ID_MINIMIZE_BUTTON, |
| 123 gfx::Size(kMinimizeButtonWidth, kCaptionButtonHeight)); |
160 maximize_button_ = InitWindowCaptionButton( | 124 maximize_button_ = InitWindowCaptionButton( |
161 VIEW_ID_MAXIMIZE_BUTTON, gfx::Size(25, 18)); | 125 VIEW_ID_MAXIMIZE_BUTTON, |
| 126 gfx::Size(kMaximizeButtonWidth, kCaptionButtonHeight)); |
162 restore_button_ = InitWindowCaptionButton( | 127 restore_button_ = InitWindowCaptionButton( |
163 VIEW_ID_RESTORE_BUTTON, gfx::Size(25, 18)); | 128 VIEW_ID_RESTORE_BUTTON, |
| 129 gfx::Size(kMaximizeButtonWidth, kCaptionButtonHeight)); |
164 close_button_ = InitWindowCaptionButton( | 130 close_button_ = InitWindowCaptionButton( |
165 VIEW_ID_CLOSE_BUTTON, gfx::Size(43, 18)); | 131 VIEW_ID_CLOSE_BUTTON, |
| 132 gfx::Size(kCloseButtonWidth, kCaptionButtonHeight)); |
166 } | 133 } |
167 | 134 |
168 void TearDown() override { | 135 void TearDown() override { |
169 widget_->CloseNow(); | 136 widget_->CloseNow(); |
170 | 137 |
171 views::ViewsTestBase::TearDown(); | 138 views::ViewsTestBase::TearDown(); |
172 } | 139 } |
173 | 140 |
174 protected: | 141 protected: |
175 views::ImageButton* InitWindowCaptionButton(ViewID view_id, | 142 views::ImageButton* InitWindowCaptionButton(ViewID view_id, |
(...skipping 20 matching lines...) Expand all Loading... |
196 window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 163 window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
197 window_title_->set_id(VIEW_ID_WINDOW_TITLE); | 164 window_title_->set_id(VIEW_ID_WINDOW_TITLE); |
198 root_view_->AddChildView(window_title_); | 165 root_view_->AddChildView(window_title_); |
199 } | 166 } |
200 | 167 |
201 void AddNewAvatarButton() { | 168 void AddNewAvatarButton() { |
202 new_avatar_button_ = | 169 new_avatar_button_ = |
203 new views::MenuButton(nullptr, base::string16(), nullptr, false); | 170 new views::MenuButton(nullptr, base::string16(), nullptr, false); |
204 new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON); | 171 new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON); |
205 root_view_->AddChildView(new_avatar_button_); | 172 root_view_->AddChildView(new_avatar_button_); |
| 173 delegate_->set_show_avatar(true); |
206 } | 174 } |
207 | 175 |
208 void ExpectBasicWindowBounds() { | 176 int CaptionY() const { |
209 EXPECT_EQ("428,1 25x18", maximize_button_->bounds().ToString()); | 177 return delegate_->IsMaximized() ? |
210 EXPECT_EQ("402,1 26x18", minimize_button_->bounds().ToString()); | 178 0 : views::NonClientFrameView::kFrameShadowThickness; |
211 EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString()); | |
212 EXPECT_EQ("453,1 43x18", close_button_->bounds().ToString()); | |
213 } | 179 } |
214 | 180 |
215 Widget* widget_; | 181 int CaptionLeft() const { |
| 182 return kWindowWidth - |
| 183 (delegate_->IsMaximized() ? kMaximizedExtraCloseWidth |
| 184 : OBFVL::kFrameBorderThickness) - |
| 185 kCaptionButtonsWidth - OBFVL::kCaptionSpacing; |
| 186 } |
| 187 |
| 188 int IconAndTitleY() const { |
| 189 // This approximates the real positioning algorithm, which is complicated. |
| 190 int total_vertical_padding = |
| 191 (delegate_->IsMaximized() || !delegate_->ShouldShowCaptionButtons()) ? |
| 192 (kCaptionButtonHeight - delegate_->GetIconSize()) : |
| 193 (OBFVL::kFrameBorderThickness + |
| 194 OBFVL::kTitlebarTopAndBottomEdgeThickness); |
| 195 return (total_vertical_padding + 1) / 2; |
| 196 } |
| 197 |
| 198 void ExpectCaptionButtons(bool caption_buttons_on_left, int extra_height) { |
| 199 if (!delegate_->ShouldShowCaptionButtons()) { |
| 200 EXPECT_FALSE(maximize_button_->visible()); |
| 201 EXPECT_FALSE(minimize_button_->visible()); |
| 202 EXPECT_FALSE(restore_button_->visible()); |
| 203 EXPECT_FALSE(close_button_->visible()); |
| 204 return; |
| 205 } |
| 206 |
| 207 bool maximized = delegate_->IsMaximized(); |
| 208 int frame_thickness = maximized ? 0 : OBFVL::kFrameBorderThickness; |
| 209 int close_width = |
| 210 kCloseButtonWidth + (maximized ? kMaximizedExtraCloseWidth : 0); |
| 211 int close_x = caption_buttons_on_left ? |
| 212 frame_thickness : (kWindowWidth - frame_thickness - close_width); |
| 213 EXPECT_EQ(close_x, close_button_->x()); |
| 214 EXPECT_EQ(CaptionY(), close_button_->y()); |
| 215 EXPECT_EQ(close_width, close_button_->width()); |
| 216 EXPECT_EQ(kCaptionButtonHeight + extra_height, close_button_->height()); |
| 217 EXPECT_TRUE(close_button_->visible()); |
| 218 views::ImageButton* visible_button = maximize_button_; |
| 219 views::ImageButton* hidden_button = restore_button_; |
| 220 if (maximized) |
| 221 std::swap(visible_button, hidden_button); |
| 222 if (caption_buttons_on_left) |
| 223 EXPECT_EQ(minimize_button_->bounds().right(), visible_button->x()); |
| 224 else |
| 225 EXPECT_EQ(close_button_->x(), visible_button->bounds().right()); |
| 226 EXPECT_EQ(close_button_->y(), visible_button->y()); |
| 227 EXPECT_EQ(kMaximizeButtonWidth, visible_button->width()); |
| 228 EXPECT_EQ(close_button_->height(), visible_button->height()); |
| 229 EXPECT_TRUE(visible_button->visible()); |
| 230 if (caption_buttons_on_left) |
| 231 EXPECT_EQ(close_button_->bounds().right(), minimize_button_->x()); |
| 232 else |
| 233 EXPECT_EQ(visible_button->x(), minimize_button_->bounds().right()); |
| 234 EXPECT_EQ(visible_button->y(), minimize_button_->y()); |
| 235 EXPECT_EQ(kMinimizeButtonWidth, minimize_button_->width()); |
| 236 EXPECT_EQ(visible_button->height(), minimize_button_->height()); |
| 237 EXPECT_TRUE(minimize_button_->visible()); |
| 238 EXPECT_FALSE(hidden_button->visible()); |
| 239 } |
| 240 |
| 241 void ExpectTabStripAndMinimumSize(bool caption_buttons_on_left) { |
| 242 int caption_buttons_width = kCaptionButtonsWidth; |
| 243 bool show_caption_buttons = delegate_->ShouldShowCaptionButtons(); |
| 244 bool maximized = delegate_->IsMaximized() || !show_caption_buttons; |
| 245 if (delegate_->ShouldShowAvatar()) { |
| 246 caption_buttons_width += new_avatar_button_->GetPreferredSize().width() + |
| 247 (maximized ? OBFVL::kCaptionSpacing |
| 248 : -GetLayoutSize(NEW_TAB_BUTTON).width()); |
| 249 } |
| 250 int tabstrip_x = GetLayoutInsets(AVATAR_ICON).right(); |
| 251 if (show_caption_buttons && caption_buttons_on_left) { |
| 252 int right_of_close = |
| 253 maximized ? kMaximizedExtraCloseWidth : OBFVL::kFrameBorderThickness; |
| 254 tabstrip_x += caption_buttons_width + right_of_close; |
| 255 } else if (!maximized) { |
| 256 tabstrip_x += kNonClientBorderThickness; |
| 257 } |
| 258 gfx::Size tabstrip_min_size(delegate_->GetTabstripPreferredSize()); |
| 259 gfx::Rect tabstrip_bounds( |
| 260 layout_manager_->GetBoundsForTabStrip(tabstrip_min_size, kWindowWidth)); |
| 261 EXPECT_EQ(tabstrip_x, tabstrip_bounds.x()); |
| 262 int maximized_top_border_height = -GetLayoutInsets(TAB).top() + 1; |
| 263 if (maximized) { |
| 264 EXPECT_EQ(maximized_top_border_height, tabstrip_bounds.y()); |
| 265 } else { |
| 266 int tabstrip_nonexcluded_y = OBFVL::kFrameBorderThickness + |
| 267 OBFVL::kNonClientRestoredExtraThickness; |
| 268 EXPECT_LE(tabstrip_bounds.y(), tabstrip_nonexcluded_y); |
| 269 } |
| 270 int caption_width = (caption_buttons_on_left || !show_caption_buttons) ? |
| 271 0 : caption_buttons_width; |
| 272 int maximized_spacing = (show_caption_buttons && !caption_buttons_on_left) ? |
| 273 (OBFVL::kNewTabCaptionCondensedSpacing + kMaximizedExtraCloseWidth) : |
| 274 OBFVL::kCaptionSpacing; |
| 275 int restored_spacing = OBFVL::kCaptionSpacing + |
| 276 (caption_buttons_on_left ? kNonClientBorderThickness |
| 277 : OBFVL::kFrameBorderThickness); |
| 278 int spacing = maximized ? maximized_spacing : restored_spacing; |
| 279 int tabstrip_width = kWindowWidth - tabstrip_x - caption_width - spacing; |
| 280 EXPECT_EQ(tabstrip_width, tabstrip_bounds.width()); |
| 281 EXPECT_EQ(tabstrip_min_size.height(), tabstrip_bounds.height()); |
| 282 maximized_spacing = (show_caption_buttons && !caption_buttons_on_left) ? |
| 283 OBFVL::kNewTabCaptionCondensedSpacing : OBFVL::kCaptionSpacing; |
| 284 restored_spacing = 2 * kNonClientBorderThickness + OBFVL::kCaptionSpacing; |
| 285 spacing = maximized ? maximized_spacing : restored_spacing; |
| 286 gfx::Size browser_view_min_size(delegate_->GetBrowserViewMinimumSize()); |
| 287 int min_width = |
| 288 browser_view_min_size.width() + tabstrip_min_size.width() + spacing; |
| 289 gfx::Size min_size(layout_manager_->GetMinimumSize(kWindowWidth)); |
| 290 EXPECT_EQ(min_width, min_size.width()); |
| 291 int restored_border_height = |
| 292 OBFVL::kFrameBorderThickness + kNonClientBorderThickness; |
| 293 int top_border_height = |
| 294 maximized ? maximized_top_border_height : restored_border_height; |
| 295 int min_height = top_border_height + browser_view_min_size.height(); |
| 296 EXPECT_EQ(min_height, min_size.height()); |
| 297 } |
| 298 |
| 299 void ExpectWindowIcon(bool caption_buttons_on_left) { |
| 300 if (caption_buttons_on_left) { |
| 301 EXPECT_TRUE(layout_manager_->IconBounds().IsEmpty()); |
| 302 return; |
| 303 } |
| 304 |
| 305 int border_thickness = |
| 306 (delegate_->IsMaximized() || !delegate_->ShouldShowCaptionButtons()) ? |
| 307 0 : OBFVL::kFrameBorderThickness; |
| 308 gfx::Rect icon_bounds(layout_manager_->IconBounds()); |
| 309 EXPECT_EQ(border_thickness + OBFVL::kIconLeftSpacing, icon_bounds.x()); |
| 310 int icon_y = |
| 311 delegate_->ShouldShowWindowTitle() ? IconAndTitleY() : border_thickness; |
| 312 EXPECT_EQ(icon_y, icon_bounds.y()); |
| 313 int icon_size = delegate_->GetIconSize(); |
| 314 EXPECT_EQ(icon_size, icon_bounds.width()); |
| 315 EXPECT_EQ(icon_size, icon_bounds.height()); |
| 316 } |
| 317 |
| 318 void ExpectWindowTitle() { |
| 319 int icon_size = delegate_->GetIconSize(); |
| 320 int title_x = |
| 321 (delegate_->IsMaximized() ? 0 : OBFVL::kFrameBorderThickness) + |
| 322 OBFVL::kIconLeftSpacing + icon_size + OBFVL::kIconTitleSpacing; |
| 323 gfx::Rect title_bounds(window_title_->bounds()); |
| 324 EXPECT_EQ(title_x, title_bounds.x()); |
| 325 EXPECT_EQ(IconAndTitleY(), title_bounds.y()); |
| 326 EXPECT_EQ(CaptionLeft() - title_x, title_bounds.width()); |
| 327 EXPECT_EQ(icon_size, title_bounds.height()); |
| 328 } |
| 329 |
| 330 void ExpectAvatar() { |
| 331 int avatar_width = new_avatar_button_->GetPreferredSize().width(); |
| 332 gfx::Rect avatar_bounds(new_avatar_button_->bounds()); |
| 333 EXPECT_EQ(CaptionLeft() - avatar_width, avatar_bounds.x()); |
| 334 EXPECT_EQ(CaptionY(), avatar_bounds.y()); |
| 335 EXPECT_EQ(avatar_width, avatar_bounds.width()); |
| 336 EXPECT_EQ(kCaptionButtonHeight, avatar_bounds.height()); |
| 337 } |
| 338 |
| 339 views::Widget* widget_; |
216 views::View* root_view_; | 340 views::View* root_view_; |
217 OpaqueBrowserFrameViewLayout* layout_manager_; | 341 OBFVL* layout_manager_; |
218 scoped_ptr<TestLayoutDelegate> delegate_; | 342 scoped_ptr<TestLayoutDelegate> delegate_; |
219 | 343 |
220 // Widgets: | 344 // Widgets: |
221 views::ImageButton* minimize_button_; | 345 views::ImageButton* minimize_button_; |
222 views::ImageButton* maximize_button_; | 346 views::ImageButton* maximize_button_; |
223 views::ImageButton* restore_button_; | 347 views::ImageButton* restore_button_; |
224 views::ImageButton* close_button_; | 348 views::ImageButton* close_button_; |
225 | 349 |
226 TabIconView* tab_icon_view_; | 350 TabIconView* tab_icon_view_; |
227 views::Label* window_title_; | 351 views::Label* window_title_; |
228 | 352 |
229 AvatarMenuButton* menu_button_; | 353 AvatarMenuButton* menu_button_; |
230 views::MenuButton* new_avatar_button_; | 354 views::MenuButton* new_avatar_button_; |
231 | 355 |
232 DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest); | 356 DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest); |
233 }; | 357 }; |
234 | 358 |
235 TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindow) { | 359 TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindow) { |
236 // Tests the layout of a default chrome window with no avatars, no window | 360 // Tests the layout of a default chrome window with no avatars, no window |
237 // titles, and a tabstrip. | 361 // titles, and a tabstrip. |
238 root_view_->Layout(); | |
239 | 362 |
240 ExpectBasicWindowBounds(); | 363 for (int i = 0; i < 2; ++i) { |
241 | 364 root_view_->Layout(); |
242 // After some visual inspection, it really does look like the tabstrip is | 365 SCOPED_TRACE(i == 0 ? "Window is restored" : "Window is maximized"); |
243 // initally positioned out of our view. | 366 ExpectCaptionButtons(false, 0); |
244 EXPECT_EQ("-1,13 398x29", | 367 ExpectTabStripAndMinimumSize(false); |
245 layout_manager_->GetBoundsForTabStrip( | 368 ExpectWindowIcon(false); |
246 delegate_->GetTabstripPreferredSize(), kWidth).ToString()); | 369 delegate_->set_maximized(true); |
247 EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString()); | 370 } |
248 | |
249 // A normal window with no window icon still produces icon bounds for | |
250 // Windows, which has a hidden icon that a user can double click on to close | |
251 // the window. | |
252 EXPECT_EQ("6,4 17x17", layout_manager_->IconBounds().ToString()); | |
253 } | |
254 | |
255 TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindowMaximized) { | |
256 // Tests the layout of a default chrome window with no avatars, no window | |
257 // titles, and a tabstrip, but maximized this time. | |
258 delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED); | |
259 root_view_->Layout(); | |
260 | |
261 // Note how the bounds start at the exact top of the window while maximized | |
262 // while they start 1 pixel below when unmaximized. | |
263 EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString()); | |
264 EXPECT_EQ("403,0 26x18", minimize_button_->bounds().ToString()); | |
265 EXPECT_EQ("429,0 25x18", restore_button_->bounds().ToString()); | |
266 EXPECT_EQ("454,0 46x18", close_button_->bounds().ToString()); | |
267 | |
268 EXPECT_EQ("-6,-3 393x29", | |
269 layout_manager_->GetBoundsForTabStrip( | |
270 delegate_->GetTabstripPreferredSize(), kWidth).ToString()); | |
271 EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString()); | |
272 | |
273 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses | |
274 // this rect, extended to the top left corner of the window. | |
275 EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString()); | |
276 } | 371 } |
277 | 372 |
278 TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithYOffset) { | 373 TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithYOffset) { |
279 // Tests the layout of a basic chrome window with the caption buttons slightly | 374 // Tests the layout of a basic chrome window with the caption buttons slightly |
280 // offset from the top of the screen (as they are on Linux). | 375 // offset from the top of the screen (as they are on Linux). |
281 layout_manager_->set_extra_caption_y(2); | 376 layout_manager_->set_extra_caption_y(2); |
282 delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED); | 377 delegate_->set_maximized(true); |
283 root_view_->Layout(); | 378 root_view_->Layout(); |
284 | 379 |
285 // Note how the bounds start at the exact top of the window, DESPITE the | 380 ExpectCaptionButtons(false, 2); |
286 // caption Y offset of 2. This ensures that we obey Fitts' Law (the buttons | 381 ExpectTabStripAndMinimumSize(false); |
287 // are clickable on the top edge of the screen). However, the buttons are 2 | 382 ExpectWindowIcon(false); |
288 // pixels taller, so the images appear to be offset by 2 pixels. | |
289 EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString()); | |
290 EXPECT_EQ("403,0 26x20", minimize_button_->bounds().ToString()); | |
291 EXPECT_EQ("429,0 25x20", restore_button_->bounds().ToString()); | |
292 EXPECT_EQ("454,0 46x20", close_button_->bounds().ToString()); | |
293 | |
294 EXPECT_EQ("-6,-3 393x29", | |
295 layout_manager_->GetBoundsForTabStrip( | |
296 delegate_->GetTabstripPreferredSize(), kWidth).ToString()); | |
297 EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString()); | |
298 | |
299 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses | |
300 // this rect, extended to the top left corner of the window. | |
301 EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString()); | |
302 } | 383 } |
303 | 384 |
304 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowButtonsOnLeft) { | 385 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowButtonsOnLeft) { |
305 // Tests the layout of a chrome window with caption buttons on the left. | 386 // Tests the layout of a chrome window with caption buttons on the left. |
306 std::vector<views::FrameButton> leading_buttons; | 387 std::vector<views::FrameButton> leading_buttons; |
307 std::vector<views::FrameButton> trailing_buttons; | 388 std::vector<views::FrameButton> trailing_buttons; |
308 leading_buttons.push_back(views::FRAME_BUTTON_CLOSE); | 389 leading_buttons.push_back(views::FRAME_BUTTON_CLOSE); |
309 leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE); | 390 leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE); |
310 leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE); | 391 leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE); |
311 layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons); | 392 layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons); |
312 root_view_->Layout(); | |
313 | 393 |
314 EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString()); | 394 for (int i = 0; i < 2; ++i) { |
315 EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString()); | 395 root_view_->Layout(); |
316 EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString()); | 396 SCOPED_TRACE(i == 0 ? "Window is restored" : "Window is maximized"); |
317 EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString()); | 397 ExpectCaptionButtons(true, 0); |
318 | 398 ExpectTabStripAndMinimumSize(true); |
319 EXPECT_EQ("92,13 398x29", | 399 ExpectWindowIcon(true); |
320 layout_manager_->GetBoundsForTabStrip( | 400 delegate_->set_maximized(true); |
321 delegate_->GetTabstripPreferredSize(), kWidth).ToString()); | 401 } |
322 EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString()); | |
323 | |
324 // If the buttons are on the left, there should be no hidden icon for the user | |
325 // to double click. | |
326 EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString()); | |
327 } | 402 } |
328 | 403 |
329 TEST_F(OpaqueBrowserFrameViewLayoutTest, WithoutCaptionButtons) { | 404 TEST_F(OpaqueBrowserFrameViewLayoutTest, WithoutCaptionButtons) { |
330 // Tests the layout of a default chrome window with no caption buttons (which | 405 // Tests the layout of a default chrome window with no caption buttons (which |
331 // should force the tab strip to be condensed). | 406 // should force the tab strip to be condensed). |
332 delegate_->SetShouldShowCaptionButtons(false); | 407 delegate_->set_show_caption_buttons(false); |
333 root_view_->Layout(); | |
334 | 408 |
335 EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString()); | 409 for (int i = 0; i < 2; ++i) { |
336 EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString()); | 410 root_view_->Layout(); |
337 EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString()); | 411 SCOPED_TRACE(i == 0 ? "Window is restored" : "Window is maximized"); |
338 EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString()); | 412 ExpectCaptionButtons(false, 0); |
339 | 413 ExpectTabStripAndMinimumSize(false); |
340 EXPECT_EQ("-6,-3 501x29", | 414 ExpectWindowIcon(false); |
341 layout_manager_->GetBoundsForTabStrip( | 415 delegate_->set_maximized(true); |
342 delegate_->GetTabstripPreferredSize(), kWidth).ToString()); | 416 } |
343 EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString()); | |
344 | |
345 // A normal window with no window icon still produces icon bounds for | |
346 // Windows, which has a hidden icon that a user can double click on to close | |
347 // the window. | |
348 EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString()); | |
349 } | 417 } |
350 | 418 |
351 TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithoutCaptionButtons) { | 419 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithTitleAndIcon) { |
352 // Tests the layout of a maximized chrome window with no caption buttons. | 420 // Tests the layout of pop up windows. |
353 delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED); | 421 delegate_->set_window_title(base::ASCIIToUTF16("Window Title")); |
354 delegate_->SetShouldShowCaptionButtons(false); | 422 AddWindowTitleIcons(); |
355 root_view_->Layout(); | |
356 | 423 |
357 EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString()); | 424 for (int i = 0; i < 2; ++i) { |
358 EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString()); | 425 root_view_->Layout(); |
359 EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString()); | 426 SCOPED_TRACE(i == 0 ? "Window is restored" : "Window is maximized"); |
360 EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString()); | 427 ExpectCaptionButtons(false, 0); |
361 | 428 ExpectWindowIcon(false); |
362 EXPECT_EQ("-6,-3 501x29", | 429 ExpectWindowTitle(); |
363 layout_manager_->GetBoundsForTabStrip( | 430 delegate_->set_maximized(true); |
364 delegate_->GetTabstripPreferredSize(), kWidth).ToString()); | 431 } |
365 EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString()); | |
366 | |
367 // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses | |
368 // this rect, extended to the top left corner of the window. | |
369 EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString()); | |
370 } | |
371 | |
372 TEST_F(OpaqueBrowserFrameViewLayoutTest, WithWindowTitleAndIcon) { | |
373 // Tests the layout of pop up windows. | |
374 delegate_->SetWindowTitle(base::ASCIIToUTF16("Window Title")); | |
375 AddWindowTitleIcons(); | |
376 root_view_->Layout(); | |
377 | |
378 // We should have the right hand side should match the BasicWindow case. | |
379 ExpectBasicWindowBounds(); | |
380 | |
381 // Check the location of the tab icon and window title. | |
382 EXPECT_EQ("6,3 17x17", tab_icon_view_->bounds().ToString()); | |
383 EXPECT_EQ("27,3 370x17", window_title_->bounds().ToString()); | |
384 } | 432 } |
385 | 433 |
386 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithNewAvatar) { | 434 TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithNewAvatar) { |
387 // Tests a normal tabstrip window with the new style avatar icon. | 435 // Tests a normal tabstrip window with the new style avatar icon. |
388 AddNewAvatarButton(); | 436 AddNewAvatarButton(); |
389 root_view_->Layout(); | |
390 | 437 |
391 ExpectBasicWindowBounds(); | 438 for (int i = 0; i < 2; ++i) { |
392 | 439 root_view_->Layout(); |
393 // Check the location of the avatar button. | 440 SCOPED_TRACE(i == 0 ? "Window is restored" : "Window is maximized"); |
394 EXPECT_EQ("385,1 12x18", new_avatar_button_->bounds().ToString()); | 441 ExpectCaptionButtons(false, 0); |
395 // The new tab button is 39px wide and slides completely under the new | 442 ExpectTabStripAndMinimumSize(false); |
396 // avatar button, thus increasing the tabstrip by that amount. | 443 ExpectAvatar(); |
397 EXPECT_EQ("-1,13 420x29", | 444 delegate_->set_maximized(true); |
398 layout_manager_->GetBoundsForTabStrip( | 445 } |
399 delegate_->GetTabstripPreferredSize(), kWidth).ToString()); | |
400 EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString()); | |
401 } | 446 } |
OLD | NEW |