| 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 |