blob: db0c77d5e0a361d8ea66b033479f90e36a1b2da3 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_
#define CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_
#include <memory>
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_ui_types.h"
#include "ui/views/layout/layout_manager.h"
class BookmarkBarView;
class BrowserView;
class BrowserViewLayoutDelegate;
class InfoBarContainerView;
class MultiContentsView;
class TabStrip;
class TabStripRegionView;
class WebAppFrameToolbarView;
namespace views {
class View;
class Label;
} // namespace views
namespace web_modal {
class WebContentsModalDialogHost;
}
namespace tabs {
class VerticalTabStripStateController;
}
// The layout manager used in chrome browser.
class BrowserViewLayout : public views::LayoutManager {
public:
// The minimum width for the normal (tabbed or web app) browser window's
// contents area. This should be wide enough that WebUI pages (e.g.
// chrome://settings) and the various associated WebUI dialogs (e.g. Import
// Bookmarks) can still be functional. This value provides a trade-off between
// browser usability and privacy - specifically, the ability to browse in a
// very small window, even on large monitors (which is why a minimum height is
// not specified). This value is used for the main browser window only, not
// for popups.
static constexpr int kMainBrowserContentsMinimumWidth = 500;
// |browser_view| may be null in tests.
BrowserViewLayout(std::unique_ptr<BrowserViewLayoutDelegate> delegate,
BrowserView* browser_view,
views::View* window_scrim,
views::View* top_container,
WebAppFrameToolbarView* web_app_frame_toolbar,
views::Label* web_app_window_title,
TabStripRegionView* tab_strip_region_view,
views::View* vertical_tab_strip_container,
views::View* toolbar,
InfoBarContainerView* infobar_container,
views::View* main_container,
views::View* contents_container,
MultiContentsView* multi_contents_view,
views::View* left_aligned_side_panel_separator,
views::View* contents_height_side_panel,
views::View* right_aligned_side_panel_separator,
views::View* side_panel_rounded_corner,
views::View* top_container_separator);
BrowserViewLayout(const BrowserViewLayout&) = delete;
BrowserViewLayout& operator=(const BrowserViewLayout&) = delete;
~BrowserViewLayout() override;
// Sets or updates views that are not available when |this| is initialized.
void set_tab_strip(TabStrip* tab_strip) { tab_strip_ = tab_strip; }
void set_webui_tab_strip(views::View* webui_tab_strip) {
webui_tab_strip_ = webui_tab_strip;
}
void set_loading_bar(views::View* loading_bar) { loading_bar_ = loading_bar; }
void set_bookmark_bar(BookmarkBarView* bookmark_bar) {
bookmark_bar_ = bookmark_bar;
}
void SetUseBrowserContentMinimumSize(bool use_browser_content_minimum_size);
web_modal::WebContentsModalDialogHost* GetWebContentsModalDialogHost();
// views::LayoutManager overrides:
void Layout(views::View* host) override;
gfx::Size GetMinimumSize(const views::View* host) const override;
gfx::Size GetPreferredSize(
const views::View* host,
const views::SizeBounds& available_size) const override;
gfx::Size GetPreferredSize(const views::View* host) const override;
std::vector<raw_ptr<views::View, VectorExperimental>>
GetChildViewsInPaintOrder(const views::View* host) const override;
// Returns the minimum acceptable width for the browser web contents.
int GetMinWebContentsWidthForTesting() const;
// Returns true if an infobar is showing.
bool IsInfobarVisible() const;
void SetDelegateForTesting(
std::unique_ptr<BrowserViewLayoutDelegate> delegate);
private:
FRIEND_TEST_ALL_PREFIXES(BrowserViewLayoutTest, BrowserViewLayout);
FRIEND_TEST_ALL_PREFIXES(BrowserViewLayoutTest, Layout);
class BrowserModalDialogHostViews;
// Layout the following controls, updating `available_bounds` to leave the
// remaining space available for future controls.
void LayoutTitleBarForWebApp(gfx::Rect& available_bounds);
void LayoutVerticalTabStrip(gfx::Rect& available_bounds);
void LayoutTabStripRegion(gfx::Rect& available_bounds);
void LayoutWebUITabStrip(gfx::Rect& available_bounds);
void LayoutToolbar(gfx::Rect& available_bounds);
void LayoutBookmarkAndInfoBars(gfx::Rect& available_bounds,
int browser_view_y);
void LayoutBookmarkBar(gfx::Rect& available_bounds);
void LayoutInfoBar(gfx::Rect& available_bounds);
// Helper struct and function for LayoutContentsContainerView that calculates
// bounds for `contents_container_` and `contents_height_side_panel_`.
struct ContentsContainerLayoutResult;
ContentsContainerLayoutResult CalculateContentsContainerLayout(
const gfx::Rect& available_bounds) const;
// Layout the `main_container_` within the available bounds.
// See browser_view.h for details of the relationship between
// `main_container_` and other views.
void LayoutContentsContainerView(const gfx::Rect& available_bounds);
// Updates `top_container_`'s bounds. The new bounds depend on the size of
// the bookmark bar and the toolbar.
void UpdateTopContainerBounds(const gfx::Rect& available_bounds);
// Returns the minimum acceptable width for the browser web contents. If split
// view is active, this includes the full split view.
int GetMinWebContentsWidth() const;
// Returns the current pref for vertical tabs by accessing the vertical
// tab strip state controller
bool ShouldDisplayVerticalTabs() const;
bool IsImmersiveModeEnabledWithoutToolbar() const;
// The delegate interface. May be a mock or replaced in tests.
std::unique_ptr<BrowserViewLayoutDelegate> delegate_;
// The owning browser view.
const raw_ptr<BrowserView> browser_view_;
// Child views that the layout manager manages.
// NOTE: If you add a view, try to add it as a views::View, which makes
// testing much easier.
const raw_ptr<views::View> window_scrim_ = nullptr;
const raw_ptr<views::View> top_container_ = nullptr;
const raw_ptr<WebAppFrameToolbarView> web_app_frame_toolbar_ = nullptr;
const raw_ptr<views::Label> web_app_window_title_ = nullptr;
const raw_ptr<TabStripRegionView> tab_strip_region_view_ = nullptr;
const raw_ptr<views::View> vertical_tab_strip_container_ = nullptr;
const raw_ptr<views::View> toolbar_ = nullptr;
const raw_ptr<InfoBarContainerView> infobar_container_ = nullptr;
const raw_ptr<views::View> main_container_ = nullptr;
const raw_ptr<views::View> contents_container_ = nullptr;
const raw_ptr<MultiContentsView> multi_contents_view_ = nullptr;
const raw_ptr<views::View> contents_height_side_panel_ = nullptr;
// TODO(crbug.com/424236535): These can be removed once `SideBySide` is
// launched.
const raw_ptr<views::View> left_aligned_side_panel_separator_ = nullptr;
const raw_ptr<views::View> right_aligned_side_panel_separator_ = nullptr;
const raw_ptr<views::View> side_panel_rounded_corner_ = nullptr;
// The contents separator used for when the top container is overlaid.
// Note: when `SideBySide` feature is disabled, this separator is also
// used when not overlaid. Once the feature is fully rolled out, we can
// rely on `MultiContentsView` to manage the contents separator when not
// overlaid (i.e. no immersive fullscreen).
const raw_ptr<views::View> top_container_separator_ = nullptr;
// These views are dynamically set.
raw_ptr<views::View> webui_tab_strip_ = nullptr;
raw_ptr<views::View> loading_bar_ = nullptr;
raw_ptr<TabStrip> tab_strip_ = nullptr;
raw_ptr<BookmarkBarView> bookmark_bar_ = nullptr;
raw_ptr<tabs::VerticalTabStripStateController>
vertical_tab_strip_controller_ = nullptr;
// The host for use in positioning the web contents browser modal dialog.
std::unique_ptr<BrowserModalDialogHostViews> dialog_host_;
// The latest dialog bounds applied during a layout pass.
gfx::Rect latest_dialog_bounds_in_screen_;
// The latest contents bounds applied during a layout pass, in screen
// coordinates.
gfx::Rect latest_contents_bounds_;
// The distance the web contents modal dialog is from the top of the dialog
// host widget.
int dialog_top_y_ = -1;
// Whether or not to use the browser based content minimum size.
bool use_browser_content_minimum_size_ = false;
};
#endif // CHROME_BROWSER_UI_VIEWS_FRAME_BROWSER_VIEW_LAYOUT_H_