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. 4 5#import "chrome/browser/ui/cocoa/browser_window_layout.h" 6 7#include "base/logging.h" 8 9namespace chrome { 10 11const CGFloat kTabStripHeight = 37; 12 13} // namespace chrome 14 15namespace { 16 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. 20const CGFloat kLocBarLeftRightInset = 1; 21const CGFloat kLocBarTopInset = 0; 22const CGFloat kLocBarBottomInset = 1; 23 24} // namespace 25 26@interface BrowserWindowLayout () 27 28// Computes the y offset to use when laying out the tab strip in fullscreen 29// mode. 30- (void)computeFullscreenYOffset; 31 32// Computes the layout of the tab strip. 33- (void)computeTabStripLayout; 34 35// Computes the layout of the subviews of the content view. 36- (void)computeContentViewLayout; 37 38// Computes the height of the backing bar for the views in the omnibox area in 39// fullscreen mode. 40- (CGFloat)fullscreenBackingBarHeight; 41 42@end 43 44@implementation BrowserWindowLayout 45 46- (chrome::LayoutOutput)computeLayout { 47 memset(&output_, 0, sizeof(chrome::LayoutOutput)); 48 49 [self computeFullscreenYOffset]; 50 [self computeTabStripLayout]; 51 [self computeContentViewLayout]; 52 53 return output_; 54} 55 56- (void)setContentViewSize:(NSSize)size { 57 parameters_.contentViewSize = size; 58} 59 60- (void)setWindowSize:(NSSize)size { 61 parameters_.windowSize = size; 62} 63 64- (void)setInAnyFullscreen:(BOOL)inAnyFullscreen { 65 parameters_.inAnyFullscreen = inAnyFullscreen; 66} 67 68- (void)setFullscreenSlidingStyle:(fullscreen_mac::SlidingStyle)slidingStyle { 69 parameters_.slidingStyle = slidingStyle; 70} 71 72- (void)setFullscreenMenubarOffset:(CGFloat)menubarOffset { 73 parameters_.menubarOffset = menubarOffset; 74} 75 76- (void)setFullscreenToolbarFraction:(CGFloat)toolbarFraction { 77 parameters_.toolbarFraction = toolbarFraction; 78} 79 80- (void)setHasTabStrip:(BOOL)hasTabStrip { 81 parameters_.hasTabStrip = hasTabStrip; 82} 83 84- (void)setHasToolbar:(BOOL)hasToolbar { 85 parameters_.hasToolbar = hasToolbar; 86} 87 88- (void)setHasLocationBar:(BOOL)hasLocationBar { 89 parameters_.hasLocationBar = hasLocationBar; 90} 91 92- (void)setToolbarHeight:(CGFloat)toolbarHeight { 93 parameters_.toolbarHeight = toolbarHeight; 94} 95 96- (void)setBookmarkBarHidden:(BOOL)bookmarkBarHidden { 97 parameters_.bookmarkBarHidden = bookmarkBarHidden; 98} 99 100- (void)setPlaceBookmarkBarBelowInfoBar:(BOOL)placeBookmarkBarBelowInfoBar { 101 parameters_.placeBookmarkBarBelowInfoBar = placeBookmarkBarBelowInfoBar; 102} 103 104- (void)setBookmarkBarHeight:(CGFloat)bookmarkBarHeight { 105 parameters_.bookmarkBarHeight = bookmarkBarHeight; 106} 107 108- (void)setInfoBarHeight:(CGFloat)infoBarHeight { 109 parameters_.infoBarHeight = infoBarHeight; 110} 111 112- (void)setPageInfoBubblePointY:(CGFloat)pageInfoBubblePointY { 113 parameters_.pageInfoBubblePointY = pageInfoBubblePointY; 114} 115 116- (void)setHasDownloadShelf:(BOOL)hasDownloadShelf { 117 parameters_.hasDownloadShelf = hasDownloadShelf; 118} 119 120- (void)setDownloadShelfHeight:(CGFloat)downloadShelfHeight { 121 parameters_.downloadShelfHeight = downloadShelfHeight; 122} 123 124- (void)computeFullscreenYOffset { 125 CGFloat yOffset = 0; 126 if (parameters_.inAnyFullscreen) { 127 yOffset += parameters_.menubarOffset; 128 switch (parameters_.slidingStyle) { 129 case fullscreen_mac::OMNIBOX_TABS_PRESENT: 130 break; 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]); 136 break; 137 } 138 } 139 fullscreenYOffset_ = yOffset; 140} 141 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); 149 } else { 150 maxY_ = parameters_.contentViewSize.height + fullscreenYOffset_; 151 } 152} 153 154- (void)computeContentViewLayout { 155 chrome::LayoutParameters parameters = parameters_; 156 CGFloat maxY = maxY_; 157 158 // Sanity-check |maxY|. 159 DCHECK_GE(maxY, 0); 160 DCHECK_LE(maxY, parameters_.contentViewSize.height + fullscreenYOffset_); 161 162 CGFloat width = parameters_.contentViewSize.width; 163 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; 176 } 177 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, 183 width, 184 parameters.bookmarkBarHeight); 185 maxY = NSMinY(output_.bookmarkFrame); 186 } 187 188 // Lay out the backing bar in fullscreen mode. 189 if (parameters_.inAnyFullscreen) { 190 output_.fullscreenBackingBarFrame = 191 NSMakeRect(0, maxY, width, [self fullscreenBackingBarHeight]); 192 } 193 194 // Place the find bar immediately below the toolbar/attached bookmark bar. 195 output_.findBarMaxY = maxY; 196 output_.fullscreenExitButtonMaxY = maxY; 197 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 202 // area. 203 maxY = parameters_.windowSize.height; 204 } 205 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); 218 } else { 219 // The info bar has 0 height, but tests still expect it in the right 220 // location. 221 output_.infoBarFrame = NSMakeRect(0, maxY, width, 0); 222 } 223 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, 229 width, 230 parameters.bookmarkBarHeight); 231 maxY = NSMinY(output_.bookmarkFrame); 232 } 233 234 // Layout the download shelf at the bottom of the content view. 235 CGFloat minY = 0; 236 if (parameters.hasDownloadShelf) { 237 output_.downloadShelfFrame = 238 NSMakeRect(0, 0, width, parameters.downloadShelfHeight); 239 minY = NSMaxY(output_.downloadShelfFrame); 240 } 241 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 247 // menu bar. 248 maxY = parameters_.windowSize.height; 249 maxY -= NSHeight(output_.toolbarFrame) + NSHeight(output_.tabStripFrame) + 250 NSHeight(output_.bookmarkFrame) + parameters.infoBarHeight; 251 } 252 253 // All the remaining space becomes the frame of the content area. 254 output_.contentAreaFrame = NSMakeRect(0, minY, width, maxY - minY); 255} 256 257- (CGFloat)fullscreenBackingBarHeight { 258 if (!parameters_.inAnyFullscreen) 259 return 0; 260 261 CGFloat totalHeight = 0; 262 if (parameters_.hasTabStrip) 263 totalHeight += chrome::kTabStripHeight; 264 265 if (parameters_.hasToolbar) { 266 totalHeight += parameters_.toolbarHeight; 267 } else if (parameters_.hasLocationBar) { 268 totalHeight += 269 parameters_.toolbarHeight + kLocBarTopInset + kLocBarBottomInset; 270 } 271 272 if (!parameters_.bookmarkBarHidden && 273 !parameters_.placeBookmarkBarBelowInfoBar) 274 totalHeight += parameters_.bookmarkBarHeight; 275 276 return totalHeight; 277} 278 279@end 280