1 // Copyright 2014 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 #import "chrome/browser/ui/cocoa/browser_window_layout.h"
7 #include "base/logging.h"
11 const CGFloat kTabStripHeight = 37;
17 // Insets for the location bar, used when the full toolbar is hidden.
18 // TODO(viettrungluu): We can argue about the "correct" insetting; I like the
19 // following best, though arguably 0 inset is better/more correct.
20 const CGFloat kLocBarLeftRightInset = 1;
21 const CGFloat kLocBarTopInset = 0;
22 const CGFloat kLocBarBottomInset = 1;
26 @interface BrowserWindowLayout ()
28 // Computes the y offset to use when laying out the tab strip in fullscreen
30 - (void)computeFullscreenYOffset;
32 // Computes the layout of the tab strip.
33 - (void)computeTabStripLayout;
35 // Computes the layout of the subviews of the content view.
36 - (void)computeContentViewLayout;
38 // Computes the height of the backing bar for the views in the omnibox area in
40 - (CGFloat)fullscreenBackingBarHeight;
44 @implementation BrowserWindowLayout
46 - (chrome::LayoutOutput)computeLayout {
47 memset(&output_, 0, sizeof(chrome::LayoutOutput));
49 [self computeFullscreenYOffset];
50 [self computeTabStripLayout];
51 [self computeContentViewLayout];
56 - (void)setContentViewSize:(NSSize)size {
57 parameters_.contentViewSize = size;
60 - (void)setWindowSize:(NSSize)size {
61 parameters_.windowSize = size;
64 - (void)setInAnyFullscreen:(BOOL)inAnyFullscreen {
65 parameters_.inAnyFullscreen = inAnyFullscreen;
68 - (void)setFullscreenSlidingStyle:(fullscreen_mac::SlidingStyle)slidingStyle {
69 parameters_.slidingStyle = slidingStyle;
72 - (void)setFullscreenMenubarOffset:(CGFloat)menubarOffset {
73 parameters_.menubarOffset = menubarOffset;
76 - (void)setFullscreenToolbarFraction:(CGFloat)toolbarFraction {
77 parameters_.toolbarFraction = toolbarFraction;
80 - (void)setHasTabStrip:(BOOL)hasTabStrip {
81 parameters_.hasTabStrip = hasTabStrip;
84 - (void)setHasToolbar:(BOOL)hasToolbar {
85 parameters_.hasToolbar = hasToolbar;
88 - (void)setHasLocationBar:(BOOL)hasLocationBar {
89 parameters_.hasLocationBar = hasLocationBar;
92 - (void)setToolbarHeight:(CGFloat)toolbarHeight {
93 parameters_.toolbarHeight = toolbarHeight;
96 - (void)setBookmarkBarHidden:(BOOL)bookmarkBarHidden {
97 parameters_.bookmarkBarHidden = bookmarkBarHidden;
100 - (void)setPlaceBookmarkBarBelowInfoBar:(BOOL)placeBookmarkBarBelowInfoBar {
101 parameters_.placeBookmarkBarBelowInfoBar = placeBookmarkBarBelowInfoBar;
104 - (void)setBookmarkBarHeight:(CGFloat)bookmarkBarHeight {
105 parameters_.bookmarkBarHeight = bookmarkBarHeight;
108 - (void)setInfoBarHeight:(CGFloat)infoBarHeight {
109 parameters_.infoBarHeight = infoBarHeight;
112 - (void)setPageInfoBubblePointY:(CGFloat)pageInfoBubblePointY {
113 parameters_.pageInfoBubblePointY = pageInfoBubblePointY;
116 - (void)setHasDownloadShelf:(BOOL)hasDownloadShelf {
117 parameters_.hasDownloadShelf = hasDownloadShelf;
120 - (void)setDownloadShelfHeight:(CGFloat)downloadShelfHeight {
121 parameters_.downloadShelfHeight = downloadShelfHeight;
124 - (void)computeFullscreenYOffset {
126 if (parameters_.inAnyFullscreen) {
127 yOffset += parameters_.menubarOffset;
128 switch (parameters_.slidingStyle) {
129 case fullscreen_mac::OMNIBOX_TABS_PRESENT:
131 case fullscreen_mac::OMNIBOX_TABS_HIDDEN:
132 // In presentation mode, |yOffset| accounts for the sliding position of
133 // the floating bar and the extra offset needed to dodge the menu bar.
134 yOffset += std::floor((1 - parameters_.toolbarFraction) *
135 [self fullscreenBackingBarHeight]);
139 fullscreenYOffset_ = yOffset;
142 - (void)computeTabStripLayout {
143 if (parameters_.hasTabStrip) {
144 maxY_ = parameters_.windowSize.height + fullscreenYOffset_;
145 CGFloat width = parameters_.contentViewSize.width;
146 output_.tabStripFrame = NSMakeRect(
147 0, maxY_ - chrome::kTabStripHeight, width, chrome::kTabStripHeight);
148 maxY_ = NSMinY(output_.tabStripFrame);
150 maxY_ = parameters_.contentViewSize.height + fullscreenYOffset_;
154 - (void)computeContentViewLayout {
155 chrome::LayoutParameters parameters = parameters_;
156 CGFloat maxY = maxY_;
158 // Sanity-check |maxY|.
160 DCHECK_LE(maxY, parameters_.contentViewSize.height + fullscreenYOffset_);
162 CGFloat width = parameters_.contentViewSize.width;
164 // Lay out the toolbar.
165 if (parameters.hasToolbar) {
166 output_.toolbarFrame = NSMakeRect(
167 0, maxY - parameters_.toolbarHeight, width, parameters_.toolbarHeight);
168 maxY = NSMinY(output_.toolbarFrame);
169 } else if (parameters_.hasLocationBar) {
170 CGFloat toolbarX = kLocBarLeftRightInset;
171 CGFloat toolbarY = maxY - parameters_.toolbarHeight - kLocBarTopInset;
172 CGFloat toolbarWidth = width - 2 * kLocBarLeftRightInset;
173 output_.toolbarFrame =
174 NSMakeRect(toolbarX, toolbarY, toolbarWidth, parameters_.toolbarHeight);
175 maxY = NSMinY(output_.toolbarFrame) - kLocBarBottomInset;
178 // Lay out the bookmark bar, if it's above the info bar.
179 if (!parameters.bookmarkBarHidden &&
180 !parameters.placeBookmarkBarBelowInfoBar) {
181 output_.bookmarkFrame = NSMakeRect(0,
182 maxY - parameters.bookmarkBarHeight,
184 parameters.bookmarkBarHeight);
185 maxY = NSMinY(output_.bookmarkFrame);
188 // Lay out the backing bar in fullscreen mode.
189 if (parameters_.inAnyFullscreen) {
190 output_.fullscreenBackingBarFrame =
191 NSMakeRect(0, maxY, width, [self fullscreenBackingBarHeight]);
194 // Place the find bar immediately below the toolbar/attached bookmark bar.
195 output_.findBarMaxY = maxY;
196 output_.fullscreenExitButtonMaxY = maxY;
198 if (parameters_.inAnyFullscreen &&
199 parameters_.slidingStyle == fullscreen_mac::OMNIBOX_TABS_HIDDEN) {
200 // If in presentation mode, reset |maxY| to top of screen, so that the
201 // floating bar slides over the things which appear to be in the content
203 maxY = parameters_.windowSize.height;
206 // Lay out the info bar. It is never hidden. The frame needs to be high
207 // enough to accomodate the top arrow, which might stretch all the way to the
208 // page info bubble icon.
209 if (parameters_.infoBarHeight != 0) {
210 CGFloat infoBarMaxY =
211 NSMinY(output_.toolbarFrame) + parameters.pageInfoBubblePointY;
212 CGFloat infoBarMinY = maxY - parameters_.infoBarHeight;
213 output_.infoBarFrame =
214 NSMakeRect(0, infoBarMinY, width, infoBarMaxY - infoBarMinY);
215 output_.infoBarMaxTopArrowHeight =
216 NSHeight(output_.infoBarFrame) - parameters_.infoBarHeight;
217 maxY = NSMinY(output_.infoBarFrame);
219 // The info bar has 0 height, but tests still expect it in the right
221 output_.infoBarFrame = NSMakeRect(0, maxY, width, 0);
224 // Lay out the bookmark bar when it is below the info bar.
225 if (!parameters.bookmarkBarHidden &&
226 parameters.placeBookmarkBarBelowInfoBar) {
227 output_.bookmarkFrame = NSMakeRect(0,
228 maxY - parameters.bookmarkBarHeight,
230 parameters.bookmarkBarHeight);
231 maxY = NSMinY(output_.bookmarkFrame);
234 // Layout the download shelf at the bottom of the content view.
236 if (parameters.hasDownloadShelf) {
237 output_.downloadShelfFrame =
238 NSMakeRect(0, 0, width, parameters.downloadShelfHeight);
239 minY = NSMaxY(output_.downloadShelfFrame);
242 if (parameters_.inAnyFullscreen &&
243 parameters_.slidingStyle == fullscreen_mac::OMNIBOX_TABS_PRESENT) {
244 // If in Canonical Fullscreen, content should be shifted down by an amount
245 // equal to all the widgets and views at the top of the window. It should
246 // not be further shifted by the appearance/disappearance of the AppKit
248 maxY = parameters_.windowSize.height;
249 maxY -= NSHeight(output_.toolbarFrame) + NSHeight(output_.tabStripFrame) +
250 NSHeight(output_.bookmarkFrame) + parameters.infoBarHeight;
253 // All the remaining space becomes the frame of the content area.
254 output_.contentAreaFrame = NSMakeRect(0, minY, width, maxY - minY);
257 - (CGFloat)fullscreenBackingBarHeight {
258 if (!parameters_.inAnyFullscreen)
261 CGFloat totalHeight = 0;
262 if (parameters_.hasTabStrip)
263 totalHeight += chrome::kTabStripHeight;
265 if (parameters_.hasToolbar) {
266 totalHeight += parameters_.toolbarHeight;
267 } else if (parameters_.hasLocationBar) {
269 parameters_.toolbarHeight + kLocBarTopInset + kLocBarBottomInset;
272 if (!parameters_.bookmarkBarHidden &&
273 !parameters_.placeBookmarkBarBelowInfoBar)
274 totalHeight += parameters_.bookmarkBarHeight;