1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/frame/browser_view_layout.h"
7 #include "chrome/browser/ui/views/frame/browser_view.h"
8 #include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h"
9 #include "chrome/browser/ui/views/frame/contents_layout_manager.h"
10 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
11 #include "chrome/browser/ui/views/infobars/infobar_container_view.h"
12 #include "chrome/browser/ui/views/tabs/tab_strip.h"
13 #include "chrome/test/base/browser_with_test_window_test.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 class MockBrowserViewLayoutDelegate
: public BrowserViewLayoutDelegate
{
18 explicit MockBrowserViewLayoutDelegate(views::View
* contents_web_view
)
19 : contents_web_view_(contents_web_view
),
20 tab_strip_visible_(true),
21 toolbar_visible_(true),
22 bookmark_bar_visible_(true),
23 download_shelf_needs_layout_(false) {
25 virtual ~MockBrowserViewLayoutDelegate() {}
27 void set_download_shelf_needs_layout(bool layout
) {
28 download_shelf_needs_layout_
= layout
;
30 void set_tab_strip_visible(bool visible
) {
31 tab_strip_visible_
= visible
;
33 void set_toolbar_visible(bool visible
) {
34 toolbar_visible_
= visible
;
36 void set_bookmark_bar_visible(bool visible
) {
37 bookmark_bar_visible_
= visible
;
40 // BrowserViewLayout::Delegate overrides:
41 virtual views::View
* GetContentsWebView() const OVERRIDE
{
42 return contents_web_view_
;
44 virtual bool IsTabStripVisible() const OVERRIDE
{
45 return tab_strip_visible_
;
47 virtual gfx::Rect
GetBoundsForTabStripInBrowserView() const OVERRIDE
{
50 virtual int GetTopInsetInBrowserView() const OVERRIDE
{
53 virtual int GetThemeBackgroundXInset() const OVERRIDE
{
56 virtual bool IsToolbarVisible() const OVERRIDE
{
57 return toolbar_visible_
;
59 virtual bool IsBookmarkBarVisible() const OVERRIDE
{
60 return bookmark_bar_visible_
;
62 virtual bool DownloadShelfNeedsLayout() const OVERRIDE
{
63 return download_shelf_needs_layout_
;
66 virtual FullscreenExitBubbleViews
* GetFullscreenExitBubble() const OVERRIDE
{
71 views::View
* contents_web_view_
;
72 bool tab_strip_visible_
;
73 bool toolbar_visible_
;
74 bool bookmark_bar_visible_
;
75 bool download_shelf_needs_layout_
;
77 DISALLOW_COPY_AND_ASSIGN(MockBrowserViewLayoutDelegate
);
80 ///////////////////////////////////////////////////////////////////////////////
82 // A simple view that prefers an initial size.
83 class MockView
: public views::View
{
85 explicit MockView(gfx::Size initial_size
)
86 : size_(initial_size
) {
87 SetBoundsRect(gfx::Rect(gfx::Point(), size_
));
89 virtual ~MockView() {}
91 // views::View overrides:
92 virtual gfx::Size
GetPreferredSize() const OVERRIDE
{
99 DISALLOW_COPY_AND_ASSIGN(MockView
);
102 ///////////////////////////////////////////////////////////////////////////////
104 class MockImmersiveModeController
: public ImmersiveModeController
{
106 MockImmersiveModeController() {}
107 virtual ~MockImmersiveModeController() {}
109 // ImmersiveModeController overrides:
110 virtual void Init(BrowserView
* browser_view
) OVERRIDE
{}
111 virtual void SetEnabled(bool enabled
) OVERRIDE
{}
112 virtual bool IsEnabled() const OVERRIDE
{ return false; }
113 virtual bool ShouldHideTabIndicators() const OVERRIDE
{ return false; }
114 virtual bool ShouldHideTopViews() const OVERRIDE
{ return false; }
115 virtual bool IsRevealed() const OVERRIDE
{ return false; }
116 virtual int GetTopContainerVerticalOffset(
117 const gfx::Size
& top_container_size
) const OVERRIDE
{ return 0; }
118 virtual ImmersiveRevealedLock
* GetRevealedLock(
119 AnimateReveal animate_reveal
) OVERRIDE WARN_UNUSED_RESULT
{ return NULL
; }
120 virtual void OnFindBarVisibleBoundsChanged(
121 const gfx::Rect
& new_visible_bounds
) OVERRIDE
{}
122 virtual void SetupForTest() OVERRIDE
{}
125 DISALLOW_COPY_AND_ASSIGN(MockImmersiveModeController
);
128 ///////////////////////////////////////////////////////////////////////////////
129 // Tests of BrowserViewLayout. Runs tests without constructing a BrowserView.
130 class BrowserViewLayoutTest
: public BrowserWithTestWindowTest
{
132 BrowserViewLayoutTest()
134 top_container_(NULL
),
137 infobar_container_(NULL
),
138 contents_container_(NULL
),
139 contents_web_view_(NULL
),
140 devtools_web_view_(NULL
) {}
141 virtual ~BrowserViewLayoutTest() {}
143 BrowserViewLayout
* layout() { return layout_
.get(); }
144 MockBrowserViewLayoutDelegate
* delegate() { return delegate_
; }
145 MockView
* root_view() { return root_view_
.get(); }
146 MockView
* top_container() { return top_container_
; }
147 TabStrip
* tab_strip() { return tab_strip_
; }
148 MockView
* toolbar() { return toolbar_
; }
149 InfoBarContainerView
* infobar_container() { return infobar_container_
; }
150 MockView
* contents_container() { return contents_container_
; }
152 // BrowserWithTestWindowTest overrides:
153 virtual void SetUp() OVERRIDE
{
154 BrowserWithTestWindowTest::SetUp();
156 root_view_
.reset(new MockView(gfx::Size(800, 600)));
158 immersive_mode_controller_
.reset(new MockImmersiveModeController
);
160 top_container_
= new MockView(gfx::Size(800, 60));
161 tab_strip_
= new TabStrip(NULL
);
162 top_container_
->AddChildView(tab_strip_
);
163 toolbar_
= new MockView(gfx::Size(800, 30));
164 top_container_
->AddChildView(toolbar_
);
165 root_view_
->AddChildView(top_container_
);
167 infobar_container_
= new InfoBarContainerView(NULL
);
168 root_view_
->AddChildView(infobar_container_
);
170 contents_web_view_
= new MockView(gfx::Size(800, 600));
171 devtools_web_view_
= new MockView(gfx::Size(800, 600));
172 devtools_web_view_
->SetVisible(false);
174 contents_container_
= new MockView(gfx::Size(800, 600));
175 contents_container_
->AddChildView(devtools_web_view_
);
176 contents_container_
->AddChildView(contents_web_view_
);
177 ContentsLayoutManager
* contents_layout_manager
=
178 new ContentsLayoutManager(devtools_web_view_
, contents_web_view_
);
179 contents_container_
->SetLayoutManager(contents_layout_manager
);
181 root_view_
->AddChildView(contents_container_
);
183 // TODO(jamescook): Attach |layout_| to |root_view_|?
184 layout_
.reset(new BrowserViewLayout
);
185 delegate_
= new MockBrowserViewLayoutDelegate(contents_web_view_
);
186 layout_
->Init(delegate_
,
188 NULL
, // BrowserView.
194 contents_layout_manager
,
195 immersive_mode_controller_
.get());
199 scoped_ptr
<BrowserViewLayout
> layout_
;
200 MockBrowserViewLayoutDelegate
* delegate_
; // Owned by |layout_|.
201 scoped_ptr
<MockView
> root_view_
;
203 // Views owned by |root_view_|.
204 MockView
* top_container_
;
205 TabStrip
* tab_strip_
;
207 InfoBarContainerView
* infobar_container_
;
208 MockView
* contents_container_
;
209 MockView
* contents_web_view_
;
210 MockView
* devtools_web_view_
;
212 scoped_ptr
<MockImmersiveModeController
> immersive_mode_controller_
;
214 DISALLOW_COPY_AND_ASSIGN(BrowserViewLayoutTest
);
217 // Test basic construction and initialization.
218 TEST_F(BrowserViewLayoutTest
, BrowserViewLayout
) {
219 EXPECT_TRUE(layout()->browser());
220 EXPECT_TRUE(layout()->GetWebContentsModalDialogHost());
221 EXPECT_FALSE(layout()->InfobarVisible());
224 // Test the core layout functions.
225 TEST_F(BrowserViewLayoutTest
, Layout
) {
226 // Simulate a window with no interesting UI.
227 delegate()->set_tab_strip_visible(false);
228 delegate()->set_toolbar_visible(false);
229 delegate()->set_bookmark_bar_visible(false);
230 layout()->Layout(root_view());
232 // Top views are zero-height.
233 EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
234 EXPECT_EQ("0,0 800x0", toolbar()->bounds().ToString());
235 EXPECT_EQ("0,0 800x0", infobar_container()->bounds().ToString());
236 // Contents split fills the window.
237 EXPECT_EQ("0,0 800x600", contents_container()->bounds().ToString());
239 // Turn on the toolbar, like in a pop-up window.
240 delegate()->set_toolbar_visible(true);
241 layout()->Layout(root_view());
243 // Now the toolbar has bounds and other views shift down.
244 EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
245 EXPECT_EQ("0,0 800x30", toolbar()->bounds().ToString());
246 EXPECT_EQ("0,30 800x0", infobar_container()->bounds().ToString());
247 EXPECT_EQ("0,30 800x570", contents_container()->bounds().ToString());
249 // TODO(jamescook): Tab strip and bookmark bar.
252 TEST_F(BrowserViewLayoutTest
, LayoutDownloadShelf
) {
253 scoped_ptr
<MockView
> download_shelf(new MockView(gfx::Size(800, 50)));
254 layout()->set_download_shelf(download_shelf
.get());
256 // If download shelf doesn't need layout, it doesn't move the bottom edge.
257 delegate()->set_download_shelf_needs_layout(false);
258 const int kBottom
= 500;
259 EXPECT_EQ(kBottom
, layout()->LayoutDownloadShelf(kBottom
));
261 // Download shelf layout moves up the bottom edge and sets visibility.
262 delegate()->set_download_shelf_needs_layout(true);
263 download_shelf
->SetVisible(false);
264 EXPECT_EQ(450, layout()->LayoutDownloadShelf(kBottom
));
265 EXPECT_TRUE(download_shelf
->visible());
266 EXPECT_EQ("0,450 0x50", download_shelf
->bounds().ToString());