OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "base/observer_list.h" | 7 #include "base/observer_list.h" |
8 #include "chrome/browser/profiles/profile.h" | 8 #include "chrome/browser/profiles/profile.h" |
9 #include "chrome/browser/ui/browser_finder.h" | 9 #include "chrome/browser/ui/browser_finder.h" |
10 #include "chrome/browser/ui/find_bar/find_bar.h" | 10 #include "chrome/browser/ui/find_bar/find_bar.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "chrome/browser/ui/views/tabs/tab_strip.h" | 22 #include "chrome/browser/ui/views/tabs/tab_strip.h" |
23 #include "chrome/browser/ui/views/toolbar_view.h" | 23 #include "chrome/browser/ui/views/toolbar_view.h" |
24 #include "chrome/browser/ui/web_contents_modal_dialog_host.h" | 24 #include "chrome/browser/ui/web_contents_modal_dialog_host.h" |
25 #include "ui/base/hit_test.h" | 25 #include "ui/base/hit_test.h" |
26 #include "ui/gfx/point.h" | 26 #include "ui/gfx/point.h" |
27 #include "ui/gfx/scrollbar_size.h" | 27 #include "ui/gfx/scrollbar_size.h" |
28 #include "ui/gfx/size.h" | 28 #include "ui/gfx/size.h" |
29 #include "ui/views/controls/single_split_view.h" | 29 #include "ui/views/controls/single_split_view.h" |
30 #include "ui/views/controls/webview/webview.h" | 30 #include "ui/views/controls/webview/webview.h" |
31 | 31 |
32 using views::View; | |
33 | |
32 namespace { | 34 namespace { |
33 | 35 |
34 // The visible height of the shadow above the tabs. Clicks in this area are | 36 // The visible height of the shadow above the tabs. Clicks in this area are |
35 // treated as clicks to the frame, rather than clicks to the tab. | 37 // treated as clicks to the frame, rather than clicks to the tab. |
36 const int kTabShadowSize = 2; | 38 const int kTabShadowSize = 2; |
37 // The vertical overlap between the TabStrip and the Toolbar. | |
38 const int kToolbarTabStripVerticalOverlap = 3; | |
39 // The number of pixels the bookmark bar should overlap the spacer by if the | 39 // The number of pixels the bookmark bar should overlap the spacer by if the |
40 // spacer is visible. | 40 // spacer is visible. |
41 const int kSpacerBookmarkBarOverlap = 1; | 41 const int kSpacerBookmarkBarOverlap = 1; |
42 // The number of pixels the metro switcher is offset from the right edge. | 42 // The number of pixels the metro switcher is offset from the right edge. |
43 const int kWindowSwitcherOffsetX = 7; | 43 const int kWindowSwitcherOffsetX = 7; |
44 // The number of pixels the constrained window should overlap the bottom | 44 // The number of pixels the constrained window should overlap the bottom |
45 // of the omnibox. | 45 // of the omnibox. |
46 const int kConstrainedWindowOverlap = 3; | 46 const int kConstrainedWindowOverlap = 3; |
47 | 47 |
48 // Combines View::ConvertPointToTarget and View::HitTest for a given |point|. | 48 // Combines View::ConvertPointToTarget and View::HitTest for a given |point|. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 observer_list_.RemoveObserver(observer); | 93 observer_list_.RemoveObserver(observer); |
94 } | 94 } |
95 | 95 |
96 const BrowserViewLayout* browser_view_layout_; | 96 const BrowserViewLayout* browser_view_layout_; |
97 | 97 |
98 ObserverList<WebContentsModalDialogHostObserver> observer_list_; | 98 ObserverList<WebContentsModalDialogHostObserver> observer_list_; |
99 | 99 |
100 DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogHostViews); | 100 DISALLOW_COPY_AND_ASSIGN(WebContentsModalDialogHostViews); |
101 }; | 101 }; |
102 | 102 |
103 // static | |
104 const int BrowserViewLayout::kToolbarTabStripVerticalOverlap = 3; | |
103 | 105 |
104 //////////////////////////////////////////////////////////////////////////////// | 106 //////////////////////////////////////////////////////////////////////////////// |
105 // BrowserViewLayout, public: | 107 // BrowserViewLayout, public: |
106 | 108 |
107 BrowserViewLayout::BrowserViewLayout() | 109 BrowserViewLayout::BrowserViewLayout() |
108 : contents_split_(NULL), | 110 : contents_split_(NULL), |
109 contents_container_(NULL), | 111 contents_container_(NULL), |
110 download_shelf_(NULL), | 112 download_shelf_(NULL), |
111 browser_view_(NULL), | 113 browser_view_(NULL), |
112 find_bar_y_(0), | 114 find_bar_y_(0), |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
324 browser_view_->frame()->GetTabStripInsets(false).top)); | 326 browser_view_->frame()->GetTabStripInsets(false).top)); |
325 } | 327 } |
326 top = LayoutToolbar(top); | 328 top = LayoutToolbar(top); |
327 top = LayoutBookmarkAndInfoBars(top); | 329 top = LayoutBookmarkAndInfoBars(top); |
328 | 330 |
329 // Top container requires updated toolbar and bookmark bar to compute size. | 331 // Top container requires updated toolbar and bookmark bar to compute size. |
330 browser_view_->top_container_->SetSize( | 332 browser_view_->top_container_->SetSize( |
331 browser_view_->top_container_->GetPreferredSize()); | 333 browser_view_->top_container_->GetPreferredSize()); |
332 | 334 |
333 int bottom = LayoutDownloadShelf(browser_view_->height()); | 335 int bottom = LayoutDownloadShelf(browser_view_->height()); |
336 // Treat a detached bookmark bar as if the web contents container is shifted | |
337 // upwards and overlaps it. | |
338 top -= GetContentsOffsetForBookmarkBar(); | |
339 // Push the actual web contents down within its container so it appears under | |
340 // the bookmark bar (or under the omnibox for instant extended suggestions). | |
334 int active_top_margin = GetTopMarginForActiveContent(); | 341 int active_top_margin = GetTopMarginForActiveContent(); |
335 top -= active_top_margin; | |
336 contents_container_->SetActiveTopMargin(active_top_margin); | 342 contents_container_->SetActiveTopMargin(active_top_margin); |
kuan
2013/04/16 14:27:16
see comment below for line 587 first, then this.
| |
337 LayoutTabContents(top, bottom); | 343 LayoutContentsSplitView(top, bottom); |
344 | |
345 // Instant extended can put suggestions in an overlay web view and its | |
346 // offset needs to account for split view layout due to infobars. | |
347 contents_container_->SetOverlayTopMargin(GetTopMarginForOverlayContent()); | |
338 | 348 |
339 // Now set the contents to display at their previous origin if we just hid the | 349 // Now set the contents to display at their previous origin if we just hid the |
340 // bookmark and/or infobars. | 350 // bookmark and/or infobars. |
341 if (active_top_margin == 0 && !old_contents_origin.IsOrigin()) { | 351 if (active_top_margin == 0 && !old_contents_origin.IsOrigin()) { |
342 gfx::Point new_contents_origin(contents->bounds().origin()); | 352 gfx::Point new_contents_origin(contents->bounds().origin()); |
343 views::View::ConvertPointToTarget(contents->parent(), browser_view_, | 353 views::View::ConvertPointToTarget(contents->parent(), browser_view_, |
344 &new_contents_origin); | 354 &new_contents_origin); |
345 active_top_margin = old_contents_origin.y() - new_contents_origin.y(); | 355 active_top_margin = old_contents_origin.y() - new_contents_origin.y(); |
346 // Special case: While normally the suggestions appear to "cover" any | 356 // Special case: While normally the suggestions appear to "cover" any |
347 // bookmark/infobars, if the suggestions are very short, they might not | 357 // bookmark/infobars, if the suggestions are very short, they might not |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 find_bar_y_ = top + browser_view_->y() - 1; | 478 find_bar_y_ = top + browser_view_->y() - 1; |
469 return LayoutInfoBar(top); | 479 return LayoutInfoBar(top); |
470 } | 480 } |
471 | 481 |
472 int BrowserViewLayout::LayoutBookmarkBar(int top) { | 482 int BrowserViewLayout::LayoutBookmarkBar(int top) { |
473 BookmarkBarView* bookmark_bar = browser_view_->bookmark_bar_view_.get(); | 483 BookmarkBarView* bookmark_bar = browser_view_->bookmark_bar_view_.get(); |
474 DCHECK(bookmark_bar); | 484 DCHECK(bookmark_bar); |
475 int y = top; | 485 int y = top; |
476 if (!browser_view_->IsBookmarkBarVisible()) { | 486 if (!browser_view_->IsBookmarkBarVisible()) { |
477 bookmark_bar->SetVisible(false); | 487 bookmark_bar->SetVisible(false); |
488 // TODO(jamescook): Don't change the bookmark bar height when it is | |
489 // invisible, so we can use its height for layout even in that state. | |
478 bookmark_bar->SetBounds(0, y, browser_view_->width(), 0); | 490 bookmark_bar->SetBounds(0, y, browser_view_->width(), 0); |
479 return y; | 491 return y; |
480 } | 492 } |
481 | 493 |
482 bookmark_bar->set_infobar_visible(InfobarVisible()); | 494 bookmark_bar->set_infobar_visible(InfobarVisible()); |
483 int bookmark_bar_height = bookmark_bar->GetPreferredSize().height(); | 495 int bookmark_bar_height = bookmark_bar->GetPreferredSize().height(); |
484 y -= views::NonClientFrameView::kClientEdgeThickness + | 496 y -= views::NonClientFrameView::kClientEdgeThickness + |
485 bookmark_bar->GetToolbarOverlap(false); | 497 bookmark_bar->GetToolbarOverlap(false); |
486 bookmark_bar->SetVisible(true); | 498 bookmark_bar->SetVisible(true); |
487 bookmark_bar->SetBounds(vertical_layout_rect_.x(), y, | 499 bookmark_bar->SetBounds(vertical_layout_rect_.x(), y, |
(...skipping 15 matching lines...) Expand all Loading... | |
503 infobar_container->SetVisible(InfobarVisible()); | 515 infobar_container->SetVisible(InfobarVisible()); |
504 int height; | 516 int height; |
505 int overlapped_top = top - infobar_container->GetVerticalOverlap(&height); | 517 int overlapped_top = top - infobar_container->GetVerticalOverlap(&height); |
506 infobar_container->SetBounds(vertical_layout_rect_.x(), | 518 infobar_container->SetBounds(vertical_layout_rect_.x(), |
507 overlapped_top, | 519 overlapped_top, |
508 vertical_layout_rect_.width(), | 520 vertical_layout_rect_.width(), |
509 height); | 521 height); |
510 return overlapped_top + height; | 522 return overlapped_top + height; |
511 } | 523 } |
512 | 524 |
513 void BrowserViewLayout::LayoutTabContents(int top, int bottom) { | 525 void BrowserViewLayout::LayoutContentsSplitView(int top, int bottom) { |
514 // The ultimate idea is to calculate bounds and reserved areas for all | 526 // |contents_split_| contains web page contents and devtools. |
515 // contents views first and then resize them all, so every view | 527 // See browser_view.h for details. |
516 // (and its contents) is resized and laid out only once. | 528 gfx::Rect contents_split_bounds(vertical_layout_rect_.x(), |
517 | 529 top, |
518 // The views hierarcy (see browser_view.h for more details): | |
519 // contents_split_ -> [contents_container_ | devtools] | |
520 | |
521 gfx::Rect contents_bounds; | |
522 gfx::Rect devtools_bounds; | |
523 | |
524 gfx::Rect contents_split_bounds(vertical_layout_rect_.x(), top, | |
525 vertical_layout_rect_.width(), | 530 vertical_layout_rect_.width(), |
526 std::max(0, bottom - top)); | 531 std::max(0, bottom - top)); |
527 gfx::Point contents_split_offset( | |
528 contents_split_bounds.x() - contents_split_->bounds().x(), | |
529 contents_split_bounds.y() - contents_split_->bounds().y()); | |
530 | |
531 // Layout resize corner and calculate reserved contents rects here as all | |
532 // contents view bounds are already determined, but not yet set at this point, | |
533 // so contents will be laid out once at most. | |
534 gfx::Rect browser_reserved_rect; | |
535 if (!browser_view_->frame_->IsMaximized() && | |
536 !browser_view_->frame_->IsFullscreen()) { | |
537 gfx::Size resize_corner_size = browser_view_->GetResizeCornerSize(); | |
538 if (!resize_corner_size.IsEmpty()) { | |
539 gfx::Rect bounds = browser_view_->GetContentsBounds(); | |
540 gfx::Point resize_corner_origin( | |
541 bounds.right() - resize_corner_size.width(), | |
542 bounds.bottom() - resize_corner_size.height()); | |
543 browser_reserved_rect = | |
544 gfx::Rect(resize_corner_origin, resize_corner_size); | |
545 } | |
546 } | |
547 | |
548 // Now it's safe to actually resize all contents views in the hierarchy. | |
549 contents_split_->SetBoundsRect(contents_split_bounds); | 532 contents_split_->SetBoundsRect(contents_split_bounds); |
550 } | 533 } |
551 | 534 |
552 int BrowserViewLayout::GetTopMarginForActiveContent() { | 535 int BrowserViewLayout::GetContentsOffsetForBookmarkBar() { |
536 // Only adjust the new tab page detached bookmark bar requires the web | |
537 // content to be offset. | |
553 BookmarkBarView* bookmark_bar = browser_view_->bookmark_bar_view_.get(); | 538 BookmarkBarView* bookmark_bar = browser_view_->bookmark_bar_view_.get(); |
554 if (!bookmark_bar || | 539 if (!bookmark_bar || |
555 !browser_view_->IsBookmarkBarVisible() || | 540 !browser_view_->IsBookmarkBarVisible() || |
556 !bookmark_bar->IsDetached()) { | 541 !bookmark_bar->IsDetached()) { |
557 return 0; | 542 return 0; |
558 } | 543 } |
559 | 544 |
545 // Dev tools. | |
560 if (contents_split_->child_at(1) && contents_split_->child_at(1)->visible()) | 546 if (contents_split_->child_at(1) && contents_split_->child_at(1)->visible()) |
561 return 0; | 547 return 0; |
562 | 548 |
563 // Adjust for separator. | 549 // Offset for the detached bookmark bar. |
564 return bookmark_bar->height() - | 550 return bookmark_bar->height() - |
565 views::NonClientFrameView::kClientEdgeThickness; | 551 views::NonClientFrameView::kClientEdgeThickness; |
566 } | 552 } |
567 | 553 |
554 int BrowserViewLayout::GetTopMarginForActiveContent() { | |
555 // During an immersive reveal, if instant extended is showing suggestions | |
556 // in the main active web view, ensure that active web view appears aligned | |
557 // with the bottom of the omnibox. | |
558 InstantUIState instant_ui_state = GetInstantUIState(); | |
559 if (instant_ui_state == kInstantUIFullPageResults && | |
560 browser_view_->immersive_mode_controller()->IsRevealed()) | |
561 return GetImmersiveInstantContentTopMargin(); | |
562 | |
563 // Usually we only use a margin if there's a detached bookmarks bar. | |
564 return GetContentsOffsetForBookmarkBar(); | |
565 } | |
566 | |
567 int BrowserViewLayout::GetTopMarginForOverlayContent() { | |
568 // During an immersive reveal, if instant extended is showing suggestions | |
569 // in an overlay web view, ensure that overlay web view appears aligned | |
570 // with the bottom of the omnibox. | |
571 InstantUIState instant_ui_state = GetInstantUIState(); | |
572 if (instant_ui_state == kInstantUIOverlay && | |
573 browser_view_->immersive_mode_controller()->IsRevealed()) | |
574 return GetImmersiveInstantContentTopMargin(); | |
575 | |
576 // Usually the overlay content is aligned with the active web content. | |
577 return 0; | |
578 } | |
579 | |
580 int BrowserViewLayout::GetImmersiveInstantContentTopMargin() { | |
581 // Compute the position of the bottom edge of the top container views, | |
582 // expressed as an offset in the coordinates of |contents_container_|, | |
583 // because the offset will be applied in |contents_container_| layout. | |
584 gfx::Point bottom_edge(0, browser_view_->top_container_->height()); | |
585 views::View::ConvertPointToTarget(browser_view_->top_container_, | |
586 contents_container_, | |
587 &bottom_edge); | |
kuan
2013/04/16 14:27:16
here, when u try to get the y-pos within |contents
| |
588 return bottom_edge.y(); | |
589 } | |
590 | |
591 BrowserViewLayout::InstantUIState BrowserViewLayout::GetInstantUIState() { | |
592 if (!browser()->search_model()->mode().is_search()) | |
593 return kInstantUINone; | |
594 | |
595 // If the search suggestions are already being displayed in the overlay | |
596 // contents then return kInstantUIOverlay. | |
597 if (contents_container_->overlay_height() > 0) | |
598 return kInstantUIOverlay; | |
599 | |
600 // Top bars stay visible until the results page notifies Chrome it is ready. | |
601 if (browser()->search_model()->top_bars_visible()) | |
602 return kInstantUINone; | |
603 | |
604 return kInstantUIFullPageResults; | |
605 } | |
606 | |
568 int BrowserViewLayout::LayoutDownloadShelf(int bottom) { | 607 int BrowserViewLayout::LayoutDownloadShelf(int bottom) { |
569 // Re-layout the shelf either if it is visible or if its close animation | 608 // Re-layout the shelf either if it is visible or if its close animation |
570 // is currently running. | 609 // is currently running. |
571 if (browser_view_->IsDownloadShelfVisible() || | 610 if (browser_view_->IsDownloadShelfVisible() || |
572 (download_shelf_ && download_shelf_->IsClosing())) { | 611 (download_shelf_ && download_shelf_->IsClosing())) { |
573 bool visible = browser()->SupportsWindowFeature( | 612 bool visible = browser()->SupportsWindowFeature( |
574 Browser::FEATURE_DOWNLOADSHELF); | 613 Browser::FEATURE_DOWNLOADSHELF); |
575 DCHECK(download_shelf_); | 614 DCHECK(download_shelf_); |
576 int height = visible ? download_shelf_->GetPreferredSize().height() : 0; | 615 int height = visible ? download_shelf_->GetPreferredSize().height() : 0; |
577 download_shelf_->SetVisible(visible); | 616 download_shelf_->SetVisible(visible); |
578 download_shelf_->SetBounds(vertical_layout_rect_.x(), bottom - height, | 617 download_shelf_->SetBounds(vertical_layout_rect_.x(), bottom - height, |
579 vertical_layout_rect_.width(), height); | 618 vertical_layout_rect_.width(), height); |
580 download_shelf_->Layout(); | 619 download_shelf_->Layout(); |
581 bottom -= height; | 620 bottom -= height; |
582 } | 621 } |
583 return bottom; | 622 return bottom; |
584 } | 623 } |
585 | 624 |
586 bool BrowserViewLayout::InfobarVisible() const { | 625 bool BrowserViewLayout::InfobarVisible() const { |
587 views::View* infobar_container = browser_view_->infobar_container_; | 626 views::View* infobar_container = browser_view_->infobar_container_; |
588 // NOTE: Can't check if the size IsEmpty() since it's always 0-width. | 627 // NOTE: Can't check if the size IsEmpty() since it's always 0-width. |
589 return browser()->SupportsWindowFeature(Browser::FEATURE_INFOBAR) && | 628 return browser()->SupportsWindowFeature(Browser::FEATURE_INFOBAR) && |
590 (infobar_container->GetPreferredSize().height() != 0); | 629 (infobar_container->GetPreferredSize().height() != 0); |
591 } | 630 } |
OLD | NEW |