Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / browser_window_layout.mm
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
9 namespace chrome {
10
11 const CGFloat kTabStripHeight = 37;
12
13 }  // namespace chrome
14
15 namespace {
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.
20 const CGFloat kLocBarLeftRightInset = 1;
21 const CGFloat kLocBarTopInset = 0;
22 const 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