OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/frame/browser_view_layout.h" | 5 #include "chrome/browser/ui/views/frame/browser_view_layout.h" |
6 | 6 |
7 #include "chrome/browser/ui/browser_finder.h" | 7 #include "chrome/browser/ui/browser_finder.h" |
8 #include "chrome/browser/ui/find_bar/find_bar.h" | 8 #include "chrome/browser/ui/find_bar/find_bar.h" |
9 #include "chrome/browser/ui/find_bar/find_bar_controller.h" | 9 #include "chrome/browser/ui/find_bar/find_bar_controller.h" |
10 #include "chrome/browser/ui/search/search_model.h" | |
11 #include "chrome/browser/ui/search/search_ui.h" | |
12 #include "chrome/browser/ui/view_ids.h" | 10 #include "chrome/browser/ui/view_ids.h" |
13 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" | 11 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" |
14 #include "chrome/browser/ui/views/download/download_shelf_view.h" | 12 #include "chrome/browser/ui/views/download/download_shelf_view.h" |
15 #include "chrome/browser/ui/views/frame/browser_frame.h" | 13 #include "chrome/browser/ui/views/frame/browser_frame.h" |
16 #include "chrome/browser/ui/views/frame/browser_view.h" | 14 #include "chrome/browser/ui/views/frame/browser_view.h" |
17 #include "chrome/browser/ui/views/frame/contents_container.h" | 15 #include "chrome/browser/ui/views/frame/contents_container.h" |
18 #include "chrome/browser/ui/views/immersive_mode_controller.h" | 16 #include "chrome/browser/ui/views/immersive_mode_controller.h" |
19 #include "chrome/browser/ui/views/infobars/infobar_container_view.h" | 17 #include "chrome/browser/ui/views/infobars/infobar_container_view.h" |
20 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 18 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
21 #include "chrome/browser/ui/views/toolbar_view.h" | 19 #include "chrome/browser/ui/views/toolbar_view.h" |
22 #include "ui/base/hit_test.h" | 20 #include "ui/base/hit_test.h" |
23 #include "ui/gfx/point.h" | 21 #include "ui/gfx/point.h" |
24 #include "ui/gfx/scrollbar_size.h" | 22 #include "ui/gfx/scrollbar_size.h" |
25 #include "ui/gfx/size.h" | 23 #include "ui/gfx/size.h" |
26 #include "ui/views/controls/single_split_view.h" | 24 #include "ui/views/controls/single_split_view.h" |
27 #include "ui/views/controls/webview/webview.h" | |
28 | 25 |
29 namespace { | 26 namespace { |
30 | 27 |
31 // The visible height of the shadow above the tabs. Clicks in this area are | 28 // The visible height of the shadow above the tabs. Clicks in this area are |
32 // treated as clicks to the frame, rather than clicks to the tab. | 29 // treated as clicks to the frame, rather than clicks to the tab. |
33 const int kTabShadowSize = 2; | 30 const int kTabShadowSize = 2; |
34 // The vertical overlap between the TabStrip and the Toolbar. | 31 // The vertical overlap between the TabStrip and the Toolbar. |
35 const int kToolbarTabStripVerticalOverlap = 3; | 32 const int kToolbarTabStripVerticalOverlap = 3; |
36 // The number of pixels the bookmark bar should overlap the spacer by if the | 33 // The number of pixels the bookmark bar should overlap the spacer by if the |
37 // spacer is visible. | 34 // spacer is visible. |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 contents_container_->SetActiveTopMargin(active_top_margin); | 281 contents_container_->SetActiveTopMargin(active_top_margin); |
285 LayoutTabContents(top, bottom); | 282 LayoutTabContents(top, bottom); |
286 // This must be done _after_ we lay out the WebContents since this | 283 // This must be done _after_ we lay out the WebContents since this |
287 // code calls back into us to find the bounding box the find bar | 284 // code calls back into us to find the bounding box the find bar |
288 // must be laid out within, and that code depends on the | 285 // must be laid out within, and that code depends on the |
289 // TabContentsContainer's bounds being up to date. | 286 // TabContentsContainer's bounds being up to date. |
290 if (browser()->HasFindBarController()) { | 287 if (browser()->HasFindBarController()) { |
291 browser()->GetFindBarController()->find_bar()->MoveWindowIfNecessary( | 288 browser()->GetFindBarController()->find_bar()->MoveWindowIfNecessary( |
292 gfx::Rect(), true); | 289 gfx::Rect(), true); |
293 } | 290 } |
294 | |
295 if (active_bookmark_bar_ && active_bookmark_bar_->IsDetached() && | |
296 browser()->search_model()->mode().is_ntp()) { | |
297 LayoutBookmarkBarAtBottom(); | |
298 } else { | |
299 #if !defined(USE_AURA) | |
300 contents_container_->SetExtraContentHeight(0); | |
301 contents_split_->SetLeadingBottomOffset(0); | |
302 #endif | |
303 } | |
304 } | 291 } |
305 | 292 |
306 // Return the preferred size which is the size required to give each | 293 // Return the preferred size which is the size required to give each |
307 // children their respective preferred size. | 294 // children their respective preferred size. |
308 gfx::Size BrowserViewLayout::GetPreferredSize(views::View* host) { | 295 gfx::Size BrowserViewLayout::GetPreferredSize(views::View* host) { |
309 return gfx::Size(); | 296 return gfx::Size(); |
310 } | 297 } |
311 | 298 |
312 ////////////////////////////////////////////////////////////////////////////// | 299 ////////////////////////////////////////////////////////////////////////////// |
313 // BrowserViewLayout, private: | 300 // BrowserViewLayout, private: |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 toolbar->SetBounds(vertical_layout_rect_.x(), y, browser_view_width, height); | 373 toolbar->SetBounds(vertical_layout_rect_.x(), y, browser_view_width, height); |
387 | 374 |
388 return y + height; | 375 return y + height; |
389 } | 376 } |
390 | 377 |
391 int BrowserViewLayout::LayoutBookmarkAndInfoBars(int top) { | 378 int BrowserViewLayout::LayoutBookmarkAndInfoBars(int top) { |
392 constrained_window_top_y_ = | 379 constrained_window_top_y_ = |
393 top + browser_view_->y() - kConstrainedWindowOverlap; | 380 top + browser_view_->y() - kConstrainedWindowOverlap; |
394 find_bar_y_ = top + browser_view_->y() - 1; | 381 find_bar_y_ = top + browser_view_->y() - 1; |
395 if (active_bookmark_bar_) { | 382 if (active_bookmark_bar_) { |
396 // If the bookmark bar is showing in detached style: | 383 // If we're showing the Bookmark bar in detached style, then we |
397 // - for non-NTP mode, show any Info bar _above_ the bookmark bar, since the | 384 // need to show any Info bar _above_ the Bookmark bar, since the |
398 // bookmark bar is styled to look like it's part of the page. | 385 // Bookmark bar is styled to look like it's part of the page. |
399 // - otherwise, show the bookmark bar at the bottom of content view, so just | 386 if (active_bookmark_bar_->IsDetached()) |
400 // lay out infobar here; bottom bookmark bar is laid out in | 387 return LayoutBookmarkBar(LayoutInfoBar(top)); |
401 // |LayoutBookmarkBarAtBottom|. | |
402 if (active_bookmark_bar_->IsDetached()) { | |
403 int infobar_top = LayoutInfoBar(top); | |
404 return browser()->search_model()->mode().is_ntp() ? | |
405 infobar_top : LayoutBookmarkBarAtTop(infobar_top); | |
406 } | |
407 // Otherwise, Bookmark bar first, Info bar second. | 388 // Otherwise, Bookmark bar first, Info bar second. |
408 top = std::max(browser_view_->toolbar_->bounds().bottom(), | 389 top = std::max(browser_view_->toolbar_->bounds().bottom(), |
409 LayoutBookmarkBarAtTop(top)); | 390 LayoutBookmarkBar(top)); |
410 } | 391 } |
411 find_bar_y_ = top + browser_view_->y() - 1; | 392 find_bar_y_ = top + browser_view_->y() - 1; |
412 return LayoutInfoBar(top); | 393 return LayoutInfoBar(top); |
413 } | 394 } |
414 | 395 |
415 int BrowserViewLayout::LayoutBookmarkBarAtTop(int top) { | 396 int BrowserViewLayout::LayoutBookmarkBar(int top) { |
416 DCHECK(active_bookmark_bar_); | 397 DCHECK(active_bookmark_bar_); |
417 int y = top; | 398 int y = top; |
418 if (!browser_view_->IsBookmarkBarVisible()) { | 399 if (!browser_view_->IsBookmarkBarVisible()) { |
419 active_bookmark_bar_->SetVisible(false); | 400 active_bookmark_bar_->SetVisible(false); |
420 active_bookmark_bar_->SetBounds(0, y, browser_view_->width(), 0); | 401 active_bookmark_bar_->SetBounds(0, y, browser_view_->width(), 0); |
421 return y; | 402 return y; |
422 } | 403 } |
423 | 404 |
424 active_bookmark_bar_->set_infobar_visible(InfobarVisible()); | 405 active_bookmark_bar_->set_infobar_visible(InfobarVisible()); |
425 int bookmark_bar_height = active_bookmark_bar_->GetPreferredSize().height(); | 406 int bookmark_bar_height = active_bookmark_bar_->GetPreferredSize().height(); |
426 y -= views::NonClientFrameView::kClientEdgeThickness + | 407 y -= views::NonClientFrameView::kClientEdgeThickness + |
427 active_bookmark_bar_->GetToolbarOverlap(false); | 408 active_bookmark_bar_->GetToolbarOverlap(false); |
428 active_bookmark_bar_->SetVisible(true); | 409 active_bookmark_bar_->SetVisible(true); |
429 active_bookmark_bar_->SetBounds(vertical_layout_rect_.x(), y, | 410 active_bookmark_bar_->SetBounds(vertical_layout_rect_.x(), y, |
430 vertical_layout_rect_.width(), | 411 vertical_layout_rect_.width(), |
431 bookmark_bar_height); | 412 bookmark_bar_height); |
432 return y + bookmark_bar_height; | 413 return y + bookmark_bar_height; |
433 } | 414 } |
434 | 415 |
435 void BrowserViewLayout::LayoutBookmarkBarAtBottom() { | |
436 DCHECK(active_bookmark_bar_); | |
437 // Layout bookmark bar at bottom of content view in the y-direction. | |
438 // Bookmark bar is child of |BrowserView| while content view is child of | |
439 // ContentsContainer, so convert its bottom coordinate relative to | |
440 // |BrowserView|. | |
441 gfx::Point content_bottom( | |
442 0, browser_view_->contents_container_->bounds().bottom()); | |
443 views::View::ConvertPointToTarget( | |
444 browser_view_->contents_container_->parent(), browser_view_, | |
445 &content_bottom); | |
446 // Only show bookmark bar if height of content view is >= | |
447 // chrome::search::kMinContentHeightForBottomBookmarkBar. | |
448 if (browser_view_->contents_container_->height() < | |
449 chrome::search::kMinContentHeightForBottomBookmarkBar || | |
450 !browser_view_->IsBookmarkBarVisible()) { | |
451 active_bookmark_bar_->SetVisible(false); | |
452 active_bookmark_bar_->SetBounds(0, content_bottom.y(), | |
453 browser_view_->width(), 0); | |
454 #if !defined(USE_AURA) | |
455 // When the bookmark bar is hidden, there is no need for a clip offset. | |
456 contents_container_->SetExtraContentHeight(0); | |
457 contents_split_->SetLeadingBottomOffset(0); | |
458 #endif // !USE_AURA | |
459 return; | |
460 } | |
461 | |
462 // BookmarkBarView uses infobar visibility to determine toolbar overlap, which | |
463 // is 0 if bookmark bar is detached and infobar is visible. Since the | |
464 // bookmark bar on the NTP is detached at bottom of content view, toolbar | |
465 // overlap is irrelevant. So set infobar visible to force no toolbar overlap. | |
466 active_bookmark_bar_->set_infobar_visible(true); | |
467 active_bookmark_bar_->SetVisible(true); | |
468 | |
469 int height = active_bookmark_bar_->GetPreferredSize().height(); | |
470 active_bookmark_bar_->SetBounds(0, content_bottom.y() - height, | |
471 vertical_layout_rect_.width(), height); | |
472 #if !defined(USE_AURA) | |
473 // Without Aura, the bookmark bar can't be layered on top of the | |
474 // contents_container_. Setting a bottom clip offset on the | |
475 // contents_container_ allows it to tell its child view that it's bigger, | |
476 // and clip it so that a theme background aligned to the bottom | |
477 // or vertically centered is properly aligned whith the bookmark bar view | |
478 // drawing of the bottom of the bitmap. | |
479 contents_container_->SetExtraContentHeight(height); | |
480 contents_split_->SetLeadingBottomOffset(height); | |
481 #endif // !USE_AURA | |
482 } | |
483 | |
484 int BrowserViewLayout::LayoutInfoBar(int top) { | 416 int BrowserViewLayout::LayoutInfoBar(int top) { |
485 InfoBarContainerView* infobar_container = browser_view_->infobar_container_; | 417 InfoBarContainerView* infobar_container = browser_view_->infobar_container_; |
486 // Raise the |infobar_container| by its vertical overlap. | 418 // Raise the |infobar_container| by its vertical overlap. |
487 infobar_container->SetVisible(InfobarVisible()); | 419 infobar_container->SetVisible(InfobarVisible()); |
488 int height; | 420 int height; |
489 int overlapped_top = top - infobar_container->GetVerticalOverlap(&height); | 421 int overlapped_top = top - infobar_container->GetVerticalOverlap(&height); |
490 infobar_container->SetBounds(vertical_layout_rect_.x(), | 422 infobar_container->SetBounds(vertical_layout_rect_.x(), |
491 overlapped_top, | 423 overlapped_top, |
492 vertical_layout_rect_.width(), | 424 vertical_layout_rect_.width(), |
493 height); | 425 height); |
494 return overlapped_top + height; | 426 return overlapped_top + height; |
495 } | 427 } |
496 | 428 |
497 void BrowserViewLayout::LayoutTabContents(int top, int bottom) { | 429 void BrowserViewLayout::LayoutTabContents(int top, int bottom) { |
498 // The ultimate idea is to calculate bounds and reserved areas for all | 430 // The ultimate idea is to calculate bounds and reserved areas for all |
499 // contents views first and then resize them all, so every view | 431 // contents views first and then resize them all, so every view |
500 // (and its contents) is resized and laid out only once. | 432 // (and its contents) is resized and laid out only once. |
501 | 433 |
502 // The views hierarcy (see browser_view.h for more details): | 434 // The views hierarcy (see browser_view.h for more details): |
503 // contents_split_ -> [contents_container_ | devtools] | 435 // contents_split_ -> [contents_container_ | devtools] |
504 | 436 |
| 437 gfx::Rect contents_bounds; |
| 438 gfx::Rect devtools_bounds; |
| 439 |
505 gfx::Rect contents_split_bounds(vertical_layout_rect_.x(), top, | 440 gfx::Rect contents_split_bounds(vertical_layout_rect_.x(), top, |
506 vertical_layout_rect_.width(), | 441 vertical_layout_rect_.width(), |
507 std::max(0, bottom - top)); | 442 std::max(0, bottom - top)); |
| 443 gfx::Point contents_split_offset( |
| 444 contents_split_bounds.x() - contents_split_->bounds().x(), |
| 445 contents_split_bounds.y() - contents_split_->bounds().y()); |
| 446 |
| 447 // Layout resize corner and calculate reserved contents rects here as all |
| 448 // contents view bounds are already determined, but not yet set at this point, |
| 449 // so contents will be laid out once at most. |
| 450 gfx::Rect browser_reserved_rect; |
| 451 if (!browser_view_->frame_->IsMaximized() && |
| 452 !browser_view_->frame_->IsFullscreen()) { |
| 453 gfx::Size resize_corner_size = browser_view_->GetResizeCornerSize(); |
| 454 if (!resize_corner_size.IsEmpty()) { |
| 455 gfx::Rect bounds = browser_view_->GetContentsBounds(); |
| 456 gfx::Point resize_corner_origin( |
| 457 bounds.right() - resize_corner_size.width(), |
| 458 bounds.bottom() - resize_corner_size.height()); |
| 459 browser_reserved_rect = |
| 460 gfx::Rect(resize_corner_origin, resize_corner_size); |
| 461 } |
| 462 } |
508 | 463 |
509 // Now it's safe to actually resize all contents views in the hierarchy. | 464 // Now it's safe to actually resize all contents views in the hierarchy. |
510 contents_split_->SetBoundsRect(contents_split_bounds); | 465 contents_split_->SetBoundsRect(contents_split_bounds); |
511 } | 466 } |
512 | 467 |
513 int BrowserViewLayout::GetTopMarginForActiveContent() { | 468 int BrowserViewLayout::GetTopMarginForActiveContent() { |
514 if (!active_bookmark_bar_ || !browser_view_->IsBookmarkBarVisible() || | 469 if (!active_bookmark_bar_ || !browser_view_->IsBookmarkBarVisible() || |
515 !active_bookmark_bar_->IsDetached() || | 470 !active_bookmark_bar_->IsDetached()) { |
516 // For |NTP| mode, detached bookmark bar does NOT overlap with top of | |
517 // content view; instead, it "overlaps" with bottom of content view, which | |
518 // is handled in |LayoutBookmarkBarAtBottom|. | |
519 browser()->search_model()->mode().is_ntp()) { | |
520 return 0; | 471 return 0; |
521 } | 472 } |
522 | 473 |
523 if (contents_split_->child_at(1) && contents_split_->child_at(1)->visible()) | 474 if (contents_split_->child_at(1) && contents_split_->child_at(1)->visible()) |
524 return 0; | 475 return 0; |
525 | 476 |
526 // Adjust for separator. | 477 // Adjust for separator. |
527 return active_bookmark_bar_->height() - | 478 return active_bookmark_bar_->height() - |
528 views::NonClientFrameView::kClientEdgeThickness; | 479 views::NonClientFrameView::kClientEdgeThickness; |
529 } | 480 } |
(...skipping 15 matching lines...) Expand all Loading... |
545 } | 496 } |
546 return bottom; | 497 return bottom; |
547 } | 498 } |
548 | 499 |
549 bool BrowserViewLayout::InfobarVisible() const { | 500 bool BrowserViewLayout::InfobarVisible() const { |
550 views::View* infobar_container = browser_view_->infobar_container_; | 501 views::View* infobar_container = browser_view_->infobar_container_; |
551 // NOTE: Can't check if the size IsEmpty() since it's always 0-width. | 502 // NOTE: Can't check if the size IsEmpty() since it's always 0-width. |
552 return browser()->SupportsWindowFeature(Browser::FEATURE_INFOBAR) && | 503 return browser()->SupportsWindowFeature(Browser::FEATURE_INFOBAR) && |
553 (infobar_container->GetPreferredSize().height() != 0); | 504 (infobar_container->GetPreferredSize().height() != 0); |
554 } | 505 } |
OLD | NEW |