1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ 6 #define CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ 7 8 #include <memory> 9 10 #include "base/compiler_specific.h" 11 #include "base/gtest_prod_util.h" 12 #include "base/macros.h" 13 #include "ui/gfx/geometry/rect.h" 14 #include "ui/gfx/geometry/size.h" 15 #include "ui/gfx/native_widget_types.h" 16 #include "ui/views/layout/layout_manager.h" 17 18 class BookmarkBarView; 19 class BrowserView; 20 class BrowserViewLayoutDelegate; 21 class ImmersiveModeController; 22 class InfoBarContainerView; 23 class TabStrip; 24 class TabStripRegionView; 25 26 namespace gfx { 27 class Point; 28 } // namespace gfx 29 30 namespace views { 31 class View; 32 class Widget; 33 } // namespace views 34 35 namespace web_modal { 36 class WebContentsModalDialogHost; 37 } 38 39 // The layout manager used in chrome browser. 40 class BrowserViewLayout : public views::LayoutManager { 41 public: 42 // The minimum width for the normal (tabbed) browser window's contents area. 43 // This should be wide enough that WebUI pages (e.g. chrome://settings) and 44 // the various associated WebUI dialogs (e.g. Import Bookmarks) can still be 45 // functional. This value provides a trade-off between browser usability and 46 // privacy - specifically, the ability to browse in a very small window, even 47 // on large monitors (which is why a minimum height is not specified). This 48 // value is used for the main browser window only, not for popups. 49 static constexpr int kMainBrowserContentsMinimumWidth = 500; 50 51 // |browser_view| may be null in tests. 52 BrowserViewLayout(std::unique_ptr<BrowserViewLayoutDelegate> delegate, 53 gfx::NativeView host_view, 54 BrowserView* browser_view, 55 views::View* top_container, 56 TabStripRegionView* tab_strip_region_view, 57 TabStrip* tab_strip, 58 views::View* toolbar, 59 InfoBarContainerView* infobar_container, 60 views::View* contents_container, 61 views::View* side_panel, 62 ImmersiveModeController* immersive_mode_controller, 63 views::View* web_footer_experiment, 64 views::View* contents_separator); 65 ~BrowserViewLayout() override; 66 67 // Sets or updates views that are not available when |this| is initialized. set_tab_strip(TabStrip * tab_strip)68 void set_tab_strip(TabStrip* tab_strip) { tab_strip_ = tab_strip; } set_webui_tab_strip(views::View * webui_tab_strip)69 void set_webui_tab_strip(views::View* webui_tab_strip) { 70 webui_tab_strip_ = webui_tab_strip; 71 } set_loading_bar(views::View * loading_bar)72 void set_loading_bar(views::View* loading_bar) { loading_bar_ = loading_bar; } set_bookmark_bar(BookmarkBarView * bookmark_bar)73 void set_bookmark_bar(BookmarkBarView* bookmark_bar) { 74 bookmark_bar_ = bookmark_bar; 75 } set_download_shelf(views::View * download_shelf)76 void set_download_shelf(views::View* download_shelf) { 77 download_shelf_ = download_shelf; 78 } set_contents_border_widget(views::Widget * contents_border_widget)79 void set_contents_border_widget(views::Widget* contents_border_widget) { 80 contents_border_widget_ = contents_border_widget; 81 } contents_border_widget()82 views::Widget* contents_border_widget() { return contents_border_widget_; } 83 84 web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost(); 85 86 // Returns the view against which the dialog is positioned and parented. 87 gfx::NativeView GetHostView(); 88 89 // Tests to see if the specified |point| (in nonclient view's coordinates) 90 // is within the views managed by the laymanager. Returns one of 91 // HitTestCompat enum defined in ui/base/hit_test.h. 92 // See also ClientView::NonClientHitTest. 93 int NonClientHitTest(const gfx::Point& point); 94 95 // views::LayoutManager overrides: 96 void Layout(views::View* host) override; 97 gfx::Size GetMinimumSize(const views::View* host) const override; 98 gfx::Size GetPreferredSize(const views::View* host) const override; 99 100 // Returns true if an infobar is showing. 101 bool IsInfobarVisible() const; 102 103 private: 104 FRIEND_TEST_ALL_PREFIXES(BrowserViewLayoutTest, BrowserViewLayout); 105 FRIEND_TEST_ALL_PREFIXES(BrowserViewLayoutTest, Layout); 106 FRIEND_TEST_ALL_PREFIXES(BrowserViewLayoutTest, LayoutDownloadShelf); 107 class WebContentsModalDialogHostViews; 108 109 // Layout the following controls, starting at |top|, returns the coordinate 110 // of the bottom of the control, for laying out the next control. 111 int LayoutTabStripRegion(int top); 112 int LayoutWebUITabStrip(int top); 113 int LayoutToolbar(int top); 114 int LayoutBookmarkAndInfoBars(int top, int browser_view_y); 115 int LayoutBookmarkBar(int top); 116 int LayoutInfoBar(int top); 117 118 // Layout the |contents_container_| view between the coordinates |top| and 119 // |bottom|. See browser_view.h for details of the relationship between 120 // |contents_container_| and other views. 121 void LayoutContentsContainerView(int top, int bottom); 122 123 // Updates |top_container_|'s bounds. The new bounds depend on the size of 124 // the bookmark bar and the toolbar. 125 void UpdateTopContainerBounds(); 126 127 // Layout the Download Shelf, returns the coordinate of the top of the 128 // control, for laying out the previous control. 129 int LayoutDownloadShelf(int bottom); 130 131 // Returns the y coordinate of the client area. 132 int GetClientAreaTop(); 133 134 // Layout the web-footer experiment if enabled, returns the top of the 135 // control. See https://crbug.com/993502. 136 int LayoutWebFooterExperiment(int bottom); 137 138 // The delegate interface. May be a mock in tests. 139 const std::unique_ptr<BrowserViewLayoutDelegate> delegate_; 140 141 // The view against which the web dialog is positioned and parented. 142 gfx::NativeView const host_view_; 143 144 // The owning browser view. 145 BrowserView* const browser_view_; 146 147 // Child views that the layout manager manages. 148 // NOTE: If you add a view, try to add it as a views::View, which makes 149 // testing much easier. 150 views::View* const top_container_; 151 TabStripRegionView* const tab_strip_region_view_; 152 views::View* const toolbar_; 153 InfoBarContainerView* const infobar_container_; 154 views::View* const contents_container_; 155 views::View* const side_panel_; 156 ImmersiveModeController* const immersive_mode_controller_; 157 views::View* const web_footer_experiment_; 158 views::View* const contents_separator_; 159 160 views::View* webui_tab_strip_ = nullptr; 161 views::View* loading_bar_ = nullptr; 162 TabStrip* tab_strip_ = nullptr; 163 BookmarkBarView* bookmark_bar_ = nullptr; 164 views::View* download_shelf_ = nullptr; 165 166 // The widget displaying a border on top of contents container for 167 // highlighting the content. Not created by default. 168 views::Widget* contents_border_widget_ = nullptr; 169 170 // The bounds within which the vertically-stacked contents of the BrowserView 171 // should be laid out within. This is just the local bounds of the 172 // BrowserView. 173 // TODO(jamescook): Remove this and just use browser_view_->GetLocalBounds(). 174 gfx::Rect vertical_layout_rect_; 175 176 // The host for use in positioning the web contents modal dialog. 177 std::unique_ptr<WebContentsModalDialogHostViews> dialog_host_; 178 179 // The latest dialog bounds applied during a layout pass. 180 gfx::Rect latest_dialog_bounds_; 181 182 // The distance the web contents modal dialog is from the top of the window, 183 // in pixels. 184 int web_contents_modal_dialog_top_y_ = -1; 185 186 DISALLOW_COPY_AND_ASSIGN(BrowserViewLayout); 187 }; 188 189 #endif // CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_ 190