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);
2106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    window_title_->set_subpixel_rendering_enabled(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() {
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    menu_button_ = new AvatarMenuButton(NULL, false);
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    menu_button_->set_id(VIEW_ID_AVATAR_BUTTON);
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    delegate_->SetShouldShowAvatar(true);
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    root_view_->AddChildView(menu_button_);
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void AddAvatarLabel() {
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    avatar_label_ = new AvatarLabel(NULL);
225d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    avatar_label_->set_id(VIEW_ID_AVATAR_LABEL);
226d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    root_view_->AddChildView(avatar_label_);
227d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
228d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    // The avatar label should only be used together with the avatar button.
229d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    AddAvatarButton();
230d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
231d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void AddNewAvatarButton() {
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)   new_avatar_button_ =
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       new views::MenuButton(NULL, base::string16(), NULL, false);
2358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)   new_avatar_button_->set_id(VIEW_ID_NEW_AVATAR_BUTTON);
2368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)   root_view_->AddChildView(new_avatar_button_);
2378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void ExpectBasicWindowBounds() {
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("428,1 25x18", maximize_button_->bounds().ToString());
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("402,1 26x18", minimize_button_->bounds().ToString());
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    EXPECT_EQ("453,1 43x18", close_button_->bounds().ToString());
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Widget* widget_;
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::View* root_view_;
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  OpaqueBrowserFrameViewLayout* layout_manager_;
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<TestLayoutDelegate> delegate_;
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Widgets:
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* minimize_button_;
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* maximize_button_;
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* restore_button_;
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::ImageButton* close_button_;
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  TabIconView* tab_icon_view_;
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  views::Label* window_title_;
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AvatarLabel* avatar_label_;
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AvatarMenuButton* menu_button_;
2628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  views::MenuButton* new_avatar_button_;
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OpaqueBrowserFrameViewLayoutTest);
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindow) {
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests the layout of a default chrome window with no avatars, no window
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // titles, and a tabstrip.
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExpectBasicWindowBounds();
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // After some visual inspection, it really does look like the tabstrip is
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // initally positioned out of our view.
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("-1,13 398x29",
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // A normal window with no window icon still produces icon bounds for
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Windows, which has a hidden icon that a user can double click on to close
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // the window.
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("6,4 17x17", layout_manager_->IconBounds().ToString());
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, BasicWindowMaximized) {
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests the layout of a default chrome window with no avatars, no window
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // titles, and a tabstrip, but maximized this time.
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note how the bounds start at the exact top of the window while maximized
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // while they start 1 pixel below when unmaximized.
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("403,0 26x18", minimize_button_->bounds().ToString());
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("429,0 25x18", restore_button_->bounds().ToString());
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("454,0 46x18", close_button_->bounds().ToString());
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("-5,-3 392x29",
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
30658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // this rect, extended to the top left corner of the window.
30758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
30858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithYOffset) {
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tests the layout of a basic chrome window with the caption buttons slightly
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // offset from the top of the screen (as they are on Linux).
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  layout_manager_->set_extra_caption_y(2);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root_view_->Layout();
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note how the bounds start at the exact top of the window, DESPITE the
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // caption Y offset of 2. This ensures that we obey Fitts' Law (the buttons
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // are clickable on the top edge of the screen). However, the buttons are 2
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // pixels taller, so the images appear to be offset by 2 pixels.
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("403,0 26x20", minimize_button_->bounds().ToString());
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("429,0 25x20", restore_button_->bounds().ToString());
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("454,0 46x20", close_button_->bounds().ToString());
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 392x29",
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("262x61", layout_manager_->GetMinimumSize(kWidth).ToString());
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // this rect, extended to the top left corner of the window.
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowButtonsOnLeft) {
337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tests the layout of a chrome window with caption buttons on the left.
338a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> leading_buttons;
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> trailing_buttons;
340a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
344a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
345a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
346a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
347a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
351a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("93,13 398x29",
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
353a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
356a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // If the buttons are on the left, there should be no hidden icon for the user
357a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to double click.
358a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
359a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
360a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
361a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WithoutCaptionButtons) {
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tests the layout of a default chrome window with no caption buttons (which
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // should force the tab strip to be condensed).
364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->SetShouldShowCaptionButtons(false);
365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
366a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
370a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 500x29",
373a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
377a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // A normal window with no window icon still produces icon bounds for
378a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Windows, which has a hidden icon that a user can double click on to close
379a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the window.
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, MaximizedWithoutCaptionButtons) {
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Tests the layout of a maximized chrome window with no caption buttons.
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetWindowState(TestLayoutDelegate::STATE_MAXIMIZED);
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetShouldShowCaptionButtons(false);
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  root_view_->Layout();
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 500x29",
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In the maximized case, OpaqueBrowserFrameView::NonClientHitTest() uses
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // this rect, extended to the top left corner of the window.
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WithWindowTitleAndIcon) {
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests the layout of pop up windows.
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate_->SetWindowTitle(base::ASCIIToUTF16("Window Title"));
40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AddWindowTitleIcons();
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // We should have the right hand side should match the BasicWindow case.
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExpectBasicWindowBounds();
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Check the location of the tab icon and window title.
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("6,3 17x17", tab_icon_view_->bounds().ToString());
41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("27,3 370x17", window_title_->bounds().ToString());
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatar) {
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Tests a normal tabstrip window with an avatar icon.
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  AddAvatarButton();
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  root_view_->Layout();
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ExpectBasicWindowBounds();
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Check the location of the avatar
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("7,11 40x29", menu_button_->bounds().ToString());
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("45,13 352x29",
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
432d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
433a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarWithButtonsOnLeft) {
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tests the layout of a chrome window with an avatar icon and caption buttons
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // on the left. The avatar icon should therefore be on the right.
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // AddAvatarLabel() also adds the avatar button.
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddAvatarLabel();
438a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> leading_buttons;
439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> trailing_buttons;
440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
441a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
442a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
443a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
446a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("73,1 25x18", maximize_button_->bounds().ToString());
447a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("47,1 26x18", minimize_button_->bounds().ToString());
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("4,1 43x18", close_button_->bounds().ToString());
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
451a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check the location of the avatar
452a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("454,11 40x29", menu_button_->bounds().ToString());
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check the tab strip bounds.
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect tab_strip_bounds = layout_manager_->GetBoundsForTabStrip(
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delegate_->GetTabstripPreferredSize(), kWidth);
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(tab_strip_bounds.x(), maximize_button_->bounds().x());
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(maximize_button_->bounds().right(), tab_strip_bounds.x());
4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(13, tab_strip_bounds.y());
4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(29, tab_strip_bounds.height());
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(avatar_label_->bounds().x(), tab_strip_bounds.right());
462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check the relative location of the avatar label to the avatar. The right
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // end of the avatar label should be slightly to the right of the right end of
4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // the avatar icon.
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(avatar_label_->bounds().right(), menu_button_->bounds().right());
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(menu_button_->bounds().x(), avatar_label_->bounds().x());
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(menu_button_->bounds().bottom(),
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            avatar_label_->bounds().bottom());
4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_GT(avatar_label_->bounds().y(), menu_button_->bounds().y());
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This means that the menu will pop out facing the left (if it were to face
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the right, it would go outside the window frame and be clipped).
475a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(menu_button_->button_on_right());
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
477a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // If the buttons are on the left, there should be no hidden icon for the user
478a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to double click.
479a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", layout_manager_->IconBounds().ToString());
480a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest,
483a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       WindowWithAvatarWithoutCaptionButtonsOnLeft) {
484a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Tests the layout of a chrome window with an avatar icon and no caption
485a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // buttons. However, the caption buttons *would* be on the left if they
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // weren't hidden, and therefore, the avatar icon should be on the right.
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The lack of caption buttons should force the tab strip to be condensed.
488a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  AddAvatarButton();
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> leading_buttons;
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<views::FrameButton> trailing_buttons;
491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_CLOSE);
492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MINIMIZE);
493a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  leading_buttons.push_back(views::FRAME_BUTTON_MAXIMIZE);
494a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  layout_manager_->SetButtonOrdering(leading_buttons, trailing_buttons);
495a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  delegate_->SetShouldShowCaptionButtons(false);
496a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  root_view_->Layout();
497a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
498a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", maximize_button_->bounds().ToString());
499a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", minimize_button_->bounds().ToString());
500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", restore_button_->bounds().ToString());
501a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_EQ("0,0 0x0", close_button_->bounds().ToString());
502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
503a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Check the location of the avatar
5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("458,0 40x24", menu_button_->bounds().ToString());
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("-5,-3 458x29",
506a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
507a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("251x61", layout_manager_->GetMinimumSize(kWidth).ToString());
509a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // A normal window with no window icon still produces icon bounds for
511a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Windows, which has a hidden icon that a user can double click on to close
512a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the window.
5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ("2,0 17x17", layout_manager_->IconBounds().ToString());
514a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
5158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithNewAvatar) {
517f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  switches::EnableNewProfileManagementForTesting(
518f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      CommandLine::ForCurrentProcess());
5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Tests a normal tabstrip window with the new style avatar icon.
5218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddNewAvatarButton();
5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  root_view_->Layout();
5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ExpectBasicWindowBounds();
5258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Check the location of the caption button
5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("385,1 12x20", new_avatar_button_->bounds().ToString());
5288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // The basic window bounds are (-1, 13 398x29). There should not be an icon
5298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // avatar in the left, and the new avatar button has an offset of 5 to its
5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // next control.
5318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("-1,13 381x29",
5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            layout_manager_->GetBoundsForTabStrip(
5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                delegate_->GetTabstripPreferredSize(), kWidth).ToString());
5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  EXPECT_EQ("261x73", layout_manager_->GetMinimumSize(kWidth).ToString());
5358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(OpaqueBrowserFrameViewLayoutTest, WindowWithAvatarLabelAndButtonOnLeft) {
538d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  AddAvatarLabel();
539d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  root_view_->Layout();
540d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
541d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  ExpectBasicWindowBounds();
542d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Check the location of the avatar label relative to the avatar button if
5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // both are displayed on the left side.
545d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // The label height and width depends on the font size and the text displayed.
546d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This may possibly change, so we don't test it here.
547d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(menu_button_->bounds().x() - 2, avatar_label_->bounds().x());
548d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(
549d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      menu_button_->bounds().bottom() - 3 - avatar_label_->bounds().height(),
550d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      avatar_label_->bounds().y());
551d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
552