Home | History | Annotate | Download | only in frame
      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.
      4 
      5 #include "chrome/browser/ui/views/frame/browser_view_layout.h"
      6 
      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_container.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"
     15 
     16 class MockBrowserViewLayoutDelegate : public BrowserViewLayoutDelegate {
     17  public:
     18   MockBrowserViewLayoutDelegate()
     19       : tab_strip_visible_(true),
     20         toolbar_visible_(true),
     21         bookmark_bar_visible_(true),
     22         download_shelf_needs_layout_(false) {
     23   }
     24   virtual ~MockBrowserViewLayoutDelegate() {}
     25 
     26   void set_download_shelf_needs_layout(bool layout) {
     27     download_shelf_needs_layout_ = layout;
     28   }
     29   void set_tab_strip_visible(bool visible) {
     30     tab_strip_visible_ = visible;
     31   }
     32   void set_toolbar_visible(bool visible) {
     33     toolbar_visible_ = visible;
     34   }
     35   void set_bookmark_bar_visible(bool visible) {
     36     bookmark_bar_visible_ = visible;
     37   }
     38 
     39   // BrowserViewLayout::Delegate overrides:
     40   virtual views::View* GetWindowSwitcherButton() const OVERRIDE {
     41     // TODO(jamescook): Add a test for Windows that exercises the layout for
     42     // this button.
     43     return NULL;
     44   }
     45   virtual bool IsTabStripVisible() const OVERRIDE {
     46     return tab_strip_visible_;
     47   }
     48   virtual gfx::Rect GetBoundsForTabStrip(views::View* tab_strip) const
     49       OVERRIDE {
     50     return gfx::Rect();
     51   }
     52   virtual bool IsToolbarVisible() const OVERRIDE {
     53     return toolbar_visible_;
     54   }
     55   virtual bool IsBookmarkBarVisible() const OVERRIDE {
     56     return bookmark_bar_visible_;
     57   }
     58   virtual bool DownloadShelfNeedsLayout() const OVERRIDE {
     59     return download_shelf_needs_layout_;
     60   }
     61 
     62   virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const OVERRIDE {
     63     return NULL;
     64   }
     65 
     66  private:
     67   bool tab_strip_visible_;
     68   bool toolbar_visible_;
     69   bool bookmark_bar_visible_;
     70   bool download_shelf_needs_layout_;
     71 
     72   DISALLOW_COPY_AND_ASSIGN(MockBrowserViewLayoutDelegate);
     73 };
     74 
     75 ///////////////////////////////////////////////////////////////////////////////
     76 
     77 // A simple view that prefers an initial size.
     78 class MockView : public views::View {
     79  public:
     80   explicit MockView(gfx::Size initial_size)
     81       : size_(initial_size) {
     82     SetBoundsRect(gfx::Rect(gfx::Point(), size_));
     83   }
     84   virtual ~MockView() {}
     85 
     86   // views::View overrides:
     87   virtual gfx::Size GetPreferredSize() OVERRIDE {
     88     return size_;
     89   }
     90 
     91  private:
     92   gfx::Size size_;
     93 
     94   DISALLOW_COPY_AND_ASSIGN(MockView);
     95 };
     96 
     97 ///////////////////////////////////////////////////////////////////////////////
     98 
     99 class MockImmersiveModeController : public ImmersiveModeController {
    100  public:
    101   MockImmersiveModeController() {}
    102   virtual ~MockImmersiveModeController() {}
    103 
    104   // ImmersiveModeController overrides:
    105   virtual void Init(Delegate* delegate,
    106                     views::Widget* widget,
    107                     views::View* top_container) OVERRIDE {}
    108   virtual void SetEnabled(bool enabled) OVERRIDE {}
    109   virtual bool IsEnabled() const OVERRIDE { return false; }
    110   virtual bool ShouldHideTabIndicators() const OVERRIDE { return false; }
    111   virtual bool ShouldHideTopViews() const OVERRIDE { return false; }
    112   virtual bool IsRevealed() const OVERRIDE { return false; }
    113   virtual int GetTopContainerVerticalOffset(
    114       const gfx::Size& top_container_size) const OVERRIDE { return 0; }
    115   virtual ImmersiveRevealedLock* GetRevealedLock(
    116       AnimateReveal animate_reveal) OVERRIDE WARN_UNUSED_RESULT { return NULL; }
    117   virtual void OnFindBarVisibleBoundsChanged(
    118       const gfx::Rect& new_visible_bounds) OVERRIDE {}
    119 
    120  private:
    121   DISALLOW_COPY_AND_ASSIGN(MockImmersiveModeController);
    122 };
    123 
    124 ///////////////////////////////////////////////////////////////////////////////
    125 // Tests of BrowserViewLayout. Runs tests without constructing a BrowserView.
    126 class BrowserViewLayoutTest : public BrowserWithTestWindowTest {
    127  public:
    128   BrowserViewLayoutTest()
    129       : delegate_(NULL),
    130         top_container_(NULL),
    131         tab_strip_(NULL),
    132         toolbar_(NULL),
    133         infobar_container_(NULL),
    134         contents_split_(NULL),
    135         contents_container_(NULL),
    136         active_web_view_(NULL) {}
    137   virtual ~BrowserViewLayoutTest() {}
    138 
    139   BrowserViewLayout* layout() { return layout_.get(); }
    140   MockBrowserViewLayoutDelegate* delegate() { return delegate_; }
    141   MockView* root_view() { return root_view_.get(); }
    142   MockView* top_container() { return top_container_; }
    143   TabStrip* tab_strip() { return tab_strip_; }
    144   MockView* toolbar() { return toolbar_; }
    145   InfoBarContainerView* infobar_container() { return infobar_container_; }
    146   MockView* contents_split() { return contents_split_; }
    147   ContentsContainer* contents_container() { return contents_container_; }
    148 
    149   // BrowserWithTestWindowTest overrides:
    150   virtual void SetUp() OVERRIDE {
    151     BrowserWithTestWindowTest::SetUp();
    152 
    153     root_view_.reset(new MockView(gfx::Size(800, 600)));
    154 
    155     immersive_mode_controller_.reset(new MockImmersiveModeController);
    156 
    157     top_container_ = new MockView(gfx::Size(800, 60));
    158     tab_strip_ = new TabStrip(NULL);
    159     top_container_->AddChildView(tab_strip_);
    160     toolbar_ = new MockView(gfx::Size(800, 30));
    161     top_container_->AddChildView(toolbar_);
    162     root_view_->AddChildView(top_container_);
    163 
    164     infobar_container_ = new InfoBarContainerView(NULL);
    165     root_view_->AddChildView(infobar_container_);
    166 
    167     contents_split_ = new MockView(gfx::Size(800, 600));
    168     active_web_view_ = new MockView(gfx::Size(800, 600));
    169     contents_container_ = new ContentsContainer(active_web_view_);
    170     contents_split_->AddChildView(contents_container_);
    171     root_view_->AddChildView(contents_split_);
    172 
    173     // TODO(jamescook): Attach |layout_| to |root_view_|?
    174     layout_.reset(new BrowserViewLayout);
    175     delegate_ = new MockBrowserViewLayoutDelegate;
    176     layout_->Init(delegate_,
    177                   browser(),
    178                   NULL,  // BrowserView.
    179                   top_container_,
    180                   tab_strip_,
    181                   toolbar_,
    182                   infobar_container_,
    183                   contents_split_,
    184                   contents_container_,
    185                   immersive_mode_controller_.get());
    186   }
    187 
    188  private:
    189   scoped_ptr<BrowserViewLayout> layout_;
    190   MockBrowserViewLayoutDelegate* delegate_;  // Owned by |layout_|.
    191   scoped_ptr<MockView> root_view_;
    192 
    193   // Views owned by |root_view_|.
    194   MockView* top_container_;
    195   TabStrip* tab_strip_;
    196   MockView* toolbar_;
    197   InfoBarContainerView* infobar_container_;
    198   MockView* contents_split_;
    199   ContentsContainer* contents_container_;
    200   MockView* active_web_view_;
    201 
    202   scoped_ptr<MockImmersiveModeController> immersive_mode_controller_;
    203 
    204   DISALLOW_COPY_AND_ASSIGN(BrowserViewLayoutTest);
    205 };
    206 
    207 // Test basic construction and initialization.
    208 TEST_F(BrowserViewLayoutTest, BrowserViewLayout) {
    209   EXPECT_TRUE(layout()->browser());
    210   EXPECT_TRUE(layout()->GetWebContentsModalDialogHost());
    211   EXPECT_FALSE(layout()->InfobarVisible());
    212 }
    213 
    214 // Test the core layout functions.
    215 TEST_F(BrowserViewLayoutTest, Layout) {
    216   // Simulate a window with no interesting UI.
    217   delegate()->set_tab_strip_visible(false);
    218   delegate()->set_toolbar_visible(false);
    219   delegate()->set_bookmark_bar_visible(false);
    220   layout()->Layout(root_view());
    221 
    222   // Top views are zero-height.
    223   EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
    224   EXPECT_EQ("0,0 800x0", toolbar()->bounds().ToString());
    225   EXPECT_EQ("0,0 800x0", infobar_container()->bounds().ToString());
    226   // Contents split fills the window.
    227   EXPECT_EQ("0,0 800x600", contents_split()->bounds().ToString());
    228 
    229   // Turn on the toolbar, like in a pop-up window.
    230   delegate()->set_toolbar_visible(true);
    231   layout()->Layout(root_view());
    232 
    233   // Now the toolbar has bounds and other views shift down.
    234   EXPECT_EQ("0,0 0x0", tab_strip()->bounds().ToString());
    235   EXPECT_EQ("0,0 800x30", toolbar()->bounds().ToString());
    236   EXPECT_EQ("0,30 800x0", infobar_container()->bounds().ToString());
    237   EXPECT_EQ("0,30 800x570", contents_split()->bounds().ToString());
    238 
    239   // TODO(jamescook): Tab strip and bookmark bar.
    240 }
    241 
    242 TEST_F(BrowserViewLayoutTest, LayoutDownloadShelf) {
    243   scoped_ptr<MockView> download_shelf(new MockView(gfx::Size(800, 50)));
    244   layout()->set_download_shelf(download_shelf.get());
    245 
    246   // If download shelf doesn't need layout, it doesn't move the bottom edge.
    247   delegate()->set_download_shelf_needs_layout(false);
    248   const int kBottom = 500;
    249   EXPECT_EQ(kBottom, layout()->LayoutDownloadShelf(kBottom));
    250 
    251   // Download shelf layout moves up the bottom edge and sets visibility.
    252   delegate()->set_download_shelf_needs_layout(true);
    253   download_shelf->SetVisible(false);
    254   EXPECT_EQ(450, layout()->LayoutDownloadShelf(kBottom));
    255   EXPECT_TRUE(download_shelf->visible());
    256   EXPECT_EQ("0,450 0x50", download_shelf->bounds().ToString());
    257 }
    258