158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/views/frame/opaque_browser_frame_view_layout.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/basictypes.h"
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/command_line.h"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/views/profiles/avatar_label.h"
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/views/profiles/avatar_menu_button.h"
1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/views/tab_icon_view.h"
1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab.h"
148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/signin/core/common/profile_management_switches.h"
1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/image/image_skia.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/image/image_skia_rep.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/text_constants.h"
1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/controls/button/image_button.h"
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/controls/button/menu_button.h"
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/controls/label.h"
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/views/test/views_test_base.h"
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)using views::Widget;
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const int kWidth = 500;
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class TestLayoutDelegate : public OpaqueBrowserFrameViewLayoutDelegate {
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  enum WindowState {
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    STATE_NORMAL,
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    STATE_MAXIMIZED,
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    STATE_MINIMIZED,
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    STATE_FULLSCREEN
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TestLayoutDelegate()
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      : show_avatar_(false),
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        show_caption_buttons_(true),
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        window_state_(STATE_NORMAL) {
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~TestLayoutDelegate() {}
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void SetWindowTitle(const base::string16& title) {
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_title_ = title;
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void SetShouldShowAvatar(bool show_avatar) {
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    show_avatar_ = show_avatar;
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetShouldShowCaptionButtons(bool show_caption_buttons) {
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    show_caption_buttons_ = show_caption_buttons;
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void SetWindowState(WindowState state) {
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_state_ = state;
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // OpaqueBrowserFrameViewLayoutDelegate overrides:
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool ShouldShowWindowIcon() const OVERRIDE {
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return !window_title_.empty();
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool ShouldShowWindowTitle() const OVERRIDE {
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return !window_title_.empty();
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual base::string16 GetWindowTitle() const OVERRIDE {
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return window_title_;
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual int GetIconSize() const OVERRIDE {
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The value on linux_aura and non-aura windows.
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return 17;
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool ShouldLeaveOffsetNearTopBorder() const OVERRIDE {
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return !IsMaximized();
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual gfx::Size GetBrowserViewMinimumSize() const OVERRIDE {
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Taken from a calculation in BrowserViewLayout.
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return gfx::Size(168, 64);
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual bool ShouldShowCaptionButtons() const OVERRIDE {
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return show_caption_buttons_;
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool ShouldShowAvatar() const OVERRIDE {
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return show_avatar_;
9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual bool IsRegularOrGuestSession() const OVERRIDE {
1008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual gfx::ImageSkia GetOTRAvatarIcon() const OVERRIDE {
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // The calculations depend on the size of the OTR resource, and chromeos
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // uses a different sized image, so hard code the size of the current
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // windows/linux one.
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    gfx::ImageSkiaRep rep(gfx::Size(40, 29), 1.0f);
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    gfx::ImageSkia image(rep);
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return image;
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool IsMaximized() const OVERRIDE {
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return window_state_ == STATE_MAXIMIZED;
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool IsMinimized() const OVERRIDE {
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return window_state_ == STATE_MINIMIZED;
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool IsFullscreen() const OVERRIDE {
12158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return window_state_ == STATE_FULLSCREEN;
12258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual bool IsTabStripVisible() const OVERRIDE {
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return window_title_.empty();
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual int GetTabStripHeight() const OVERRIDE {
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return IsTabStripVisible() ? Tab::GetMinimumUnselectedSize().height() : 0;
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual gfx::Size GetTabstripPreferredSize() const OVERRIDE {
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Measured from Tabstrip::GetPreferredSize().
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return IsTabStripVisible() ? gfx::Size(78, 29) : gfx::Size(0, 0);
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::string16 window_title_;
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool show_avatar_;
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool show_caption_buttons_;
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  WindowState window_state_;
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestLayoutDelegate);
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class OpaqueBrowserFrameViewLayoutTest : public views::ViewsTestBase {
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OpaqueBrowserFrameViewLayoutTest() {}
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~OpaqueBrowserFrameViewLayoutTest() {}
15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    views::ViewsTestBase::SetUp();
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    delegate_.reset(new TestLayoutDelegate);
15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    layout_manager_ = new OpaqueBrowserFrameViewLayout(delegate_.get());
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    layout_manager_->set_extra_caption_y(0);
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    layout_manager_->set_window_caption_spacing(0);
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    widget_ = new Widget;
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    widget_->Init(CreateParams(Widget::InitParams::TYPE_POPUP));
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_ = widget_->GetRootView();
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_->SetSize(gfx::Size(kWidth, kWidth));
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_->SetLayoutManager(layout_manager_);
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Add the caption buttons. We use fake images because we're modeling the
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // Windows assets here, while the linux version uses differently sized
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // assets.
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    //
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // TODO(erg): In a follow up patch, separate these sizes out into virtual
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // accessors so we can test both the windows and linux behaviours once we
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    // start modifying the code.
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    minimize_button_ = InitWindowCaptionButton(
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        VIEW_ID_MINIMIZE_BUTTON, gfx::Size(26, 18));
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    maximize_button_ = InitWindowCaptionButton(
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        VIEW_ID_MAXIMIZE_BUTTON, gfx::Size(25, 18));
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    restore_button_ = InitWindowCaptionButton(
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        VIEW_ID_RESTORE_BUTTON, gfx::Size(25, 18));
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    close_button_ = InitWindowCaptionButton(
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        VIEW_ID_CLOSE_BUTTON, gfx::Size(43, 18));
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void TearDown() OVERRIDE {
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    widget_->CloseNow();
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    views::ViewsTestBase::TearDown();
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected:
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* InitWindowCaptionButton(ViewID view_id,
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                              const gfx::Size& size) {
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    views::ImageButton* button = new views::ImageButton(NULL);
19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    gfx::ImageSkiaRep rep(size, 1.0f);
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    gfx::ImageSkia image(rep);
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    button->SetImage(views::CustomButton::STATE_NORMAL, &image);
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    button->set_id(view_id);
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_->AddChildView(button);
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return button;
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void AddWindowTitleIcons() {
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tab_icon_view_ = new TabIconView(NULL, NULL);
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    tab_icon_view_->set_is_light(true);
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    tab_icon_view_->set_id(VIEW_ID_WINDOW_ICON);
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_->AddChildView(tab_icon_view_);
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window_title_ = new views::Label(delegate_->GetWindowTitle());
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_title_->SetVisible(delegate_->ShouldShowWindowTitle());
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_title_->SetEnabledColor(SK_ColorWHITE);
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    window_title_->SetSubpixelRenderingEnabled(false);
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    window_title_->set_id(VIEW_ID_WINDOW_TITLE);
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_->AddChildView(window_title_);
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void AddAvatarButton() {
2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Disable the New Avatar Menu.
2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    switches::DisableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    menu_button_ = new AvatarMenuButton(NULL, false);
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    menu_button_->set_id(VIEW_ID_AVATAR_BUTTON);
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    delegate_->SetShouldShowAvatar(true);
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_->AddChildView(menu_button_);
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void AddAvatarLabel() {
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    avatar_label_ = new AvatarLabel(NULL);
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    avatar_label_->set_id(VIEW_ID_AVATAR_LABEL);
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    root_view_->AddChildView(avatar_label_);
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The avatar label should only be used together with the avatar button.
232d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    AddAvatarButton();
233d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
234d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void AddNewAvatarButton() {
2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Enable the New Avatar Menu.
2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    switches::EnableNewAvatarMenuForTesting(CommandLine::ForCurrentProcess());
2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    new_avatar_button_ =
2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new views::MenuButton(NULL, base::string16(), NULL, false);
2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON);
2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    root_view_->AddChildView(new_avatar_button_);
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void ExpectBasicWindowBounds() {
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("428,1 25x18", maximize_button_->bounds().ToString());
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("402,1 26x18", minimize_button_->bounds().ToString());
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("453,1 43x18", close_button_->bounds().ToString());
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Widget* widget_;
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::View* root_view_;
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OpaqueBrowserFrameViewLayout* layout_manager_;
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<TestLayoutDelegate> delegate_;
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Widgets:
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* minimize_button_;
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* maximize_button_;
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* restore_button_;
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* close_button_;
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TabIconView* tab_icon_view_;
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::Label* window_title_;
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AvatarLabel* avatar_label_;
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AvatarMenuButton* menu_button_;
2688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  views::MenuButton* new_avatar_button_;
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest);
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindow) {
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests the layout of a default chrome window with no avatars, no window
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // titles, and a tabstrip.
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExpectBasicWindowBounds();
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // After some visual inspection, it really does look like the tabstrip is
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // initally positioned out of our view.
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("-1,13 398x29",
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // A normal window with no window icon still produces icon bounds for
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Windows, which has a hidden icon that a user can double click on to close
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the window.
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("6,4 17x17", layout_manager_->IconBounds().ToString());
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindowMaximized) {
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests the layout of a default chrome window with no avatars, no window
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // titles, and a tabstrip, but maximized this time.
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note how the bounds start at the exact top of the window while maximized
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // while they start 1 pixel below when unmaximized.
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("403,0 26x18", minimize_button_->bounds().ToString());
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("429,0 25x18", restore_button_->bounds().ToString());
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("454,0 46x18", close_button_->bounds().ToString());
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("-5,-3 392x29",
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // this rect, extended to the top left corner of the window.
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithYOffset) {
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tests the layout of a basic chrome window with the caption buttons slightly
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // offset from the top of the screen (as they are on Linux).
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  layout_manager_->set_extra_caption_y(2);
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root_view_->Layout();
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note how the bounds start at the exact top of the window, DESPITE the
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // caption Y offset of 2. This ensures that we obey Fitts' Law (the buttons
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // are clickable on the top edge of the screen). However, the buttons are 2
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // pixels taller, so the images appear to be offset by 2 pixels.
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("403,0 26x20", minimize_button_->bounds().ToString());
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("429,0 25x20", restore_button_->bounds().ToString());
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("454,0 46x20", close_button_->bounds().ToString());
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 392x29",
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // this rect, extended to the top left corner of the window.
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowButtonsOnLeft) {
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tests the layout of a chrome window with caption buttons on the left.
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> leading_buttons;
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> trailing_buttons;
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("93,13 398x29",
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
362a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // If the buttons are on the left, there should be no hidden icon for the user
363a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to double click.
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WithoutCaptionButtons) {
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tests the layout of a default chrome window with no caption buttons (which
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // should force the tab strip to be condensed).
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->SetShouldShowCaptionButtons(false);
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 500x29",
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
382a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
383a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // A normal window with no window icon still produces icon bounds for
384a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Windows, which has a hidden icon that a user can double click on to close
385a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the window.
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithoutCaptionButtons) {
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tests the layout of a maximized chrome window with no caption buttons.
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetShouldShowCaptionButtons(false);
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root_view_->Layout();
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 500x29",
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // this rect, extended to the top left corner of the window.
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WithWindowTitleAndIcon) {
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests the layout of pop up windows.
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetWindowTitle(base::ASCIIToUTF16("Window Title"));
41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AddWindowTitleIcons();
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // We should have the right hand side should match the BasicWindow case.
41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExpectBasicWindowBounds();
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Check the location of the tab icon and window title.
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("6,3 17x17", tab_icon_view_->bounds().ToString());
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("27,3 370x17", window_title_->bounds().ToString());
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatar) {
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests a normal tabstrip window with an avatar icon.
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AddAvatarButton();
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExpectBasicWindowBounds();
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Check the location of the avatar
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("7,11 40x29", menu_button_->bounds().ToString());
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("45,13 352x29",
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
438d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarWithButtonsOnLeft) {
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tests the layout of a chrome window with an avatar icon and caption buttons
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // on the left. The avatar icon should therefore be on the right.
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // AddAvatarLabel() also adds the avatar button.
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddAvatarLabel();
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> leading_buttons;
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> trailing_buttons;
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
455a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
456a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
457a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check the location of the avatar
458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("454,11 40x29", menu_button_->bounds().ToString());
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check the tab strip bounds.
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect tab_strip_bounds = layout_manager_->GetBoundsForTabStrip(
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delegate_->GetTabstripPreferredSize(), kWidth);
4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(tab_strip_bounds.x(), maximize_button_->bounds().x());
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(maximize_button_->bounds().right(), tab_strip_bounds.x());
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(13, tab_strip_bounds.y());
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(29, tab_strip_bounds.height());
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(avatar_label_->bounds().x(), tab_strip_bounds.right());
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
469a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check the relative location of the avatar label to the avatar. The right
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // end of the avatar label should be slightly to the right of the right end of
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the avatar icon.
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(avatar_label_->bounds().right(), menu_button_->bounds().right());
4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(menu_button_->bounds().x(), avatar_label_->bounds().x());
4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(menu_button_->bounds().bottom(),
4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            avatar_label_->bounds().bottom());
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(avatar_label_->bounds().y(), menu_button_->bounds().y());
4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This means that the menu will pop out facing the left (if it were to face
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the right, it would go outside the window frame and be clipped).
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(menu_button_->button_on_right());
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // If the buttons are on the left, there should be no hidden icon for the user
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to double click.
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest,
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       WindowWithAvatarWithoutCaptionButtonsOnLeft) {
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tests the layout of a chrome window with an avatar icon and no caption
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // buttons. However, the caption buttons *would* be on the left if they
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // weren't hidden, and therefore, the avatar icon should be on the right.
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The lack of caption buttons should force the tab strip to be condensed.
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddAvatarButton();
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> leading_buttons;
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> trailing_buttons;
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->SetShouldShowCaptionButtons(false);
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
504a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
505a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
508a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check the location of the avatar
5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("458,0 40x24", menu_button_->bounds().ToString());
5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 458x29",
512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
513a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
515a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
516a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // A normal window with no window icon still produces icon bounds for
517a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Windows, which has a hidden icon that a user can double click on to close
518a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the window.
5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
5218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithNewAvatar) {
5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Tests a normal tabstrip window with the new style avatar icon.
5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddNewAvatarButton();
5258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  root_view_->Layout();
5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ExpectBasicWindowBounds();
5288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Check the location of the avatar button.
5306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_EQ("385,1 12x18", new_avatar_button_->bounds().ToString());
5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The new tab button is 39px wide and slides completely under the new
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // avatar button, thus increasing the tabstrip by that amount.
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("-1,13 420x29",
5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
5358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarLabelAndButtonOnLeft) {
540d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  AddAvatarLabel();
541d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  root_view_->Layout();
542d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
543d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ExpectBasicWindowBounds();
544d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check the location of the avatar label relative to the avatar button if
5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // both are displayed on the left side.
547d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The label height and width depends on the font size and the text displayed.
548d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This may possibly change, so we don't test it here.
549d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(menu_button_->bounds().x() - 2, avatar_label_->bounds().x());
550d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(
551d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      menu_button_->bounds().bottom() - 3 - avatar_label_->bounds().height(),
552d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      avatar_label_->bounds().y());
553d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
554