Index: chrome/browser/ui/views/frame/browser_view_layout.cc |
=================================================================== |
--- chrome/browser/ui/views/frame/browser_view_layout.cc (revision 71256) |
+++ chrome/browser/ui/views/frame/browser_view_layout.cc (working copy) |
@@ -13,10 +13,12 @@ |
#include "chrome/browser/ui/views/frame/browser_frame.h" |
#include "chrome/browser/ui/views/frame/browser_view.h" |
#include "chrome/browser/ui/views/frame/contents_container.h" |
+#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" |
#include "chrome/browser/ui/views/tabs/side_tab_strip.h" |
#include "chrome/browser/ui/views/tabs/tab_strip.h" |
#include "chrome/browser/ui/views/toolbar_view.h" |
#include "gfx/scrollbar_size.h" |
+#include "views/controls/single_split_view.h" |
#include "views/window/window.h" |
#if defined(OS_LINUX) |
@@ -207,9 +209,9 @@ |
void BrowserViewLayout::ViewAdded(views::View* host, views::View* view) { |
switch (view->GetID()) { |
case VIEW_ID_CONTENTS_SPLIT: { |
- contents_split_ = view; |
+ contents_split_ = static_cast<views::SingleSplitView*>(view); |
// We're installed as the LayoutManager before BrowserView creates the |
- // contents, so we have to set contents_container_ here rather than |
+ // contents, so we have to set contents_container_ here rather than in |
// Installed. |
contents_container_ = browser_view_->contents_; |
break; |
@@ -363,9 +365,112 @@ |
return top + height; |
} |
+// |browser_reserved_rect| is in browser_view_ coordinates. |
+// |future_source_bounds| is in |source|'s parent coordinates. |
+// |future_parent_offset| is required, since parent view is not moved yet. |
+// Note that |future_parent_offset| is relative to browser_view_, not to |
+// the parent view. |
+void BrowserViewLayout::UpdateReservedContentsRect( |
+ const gfx::Rect& browser_reserved_rect, |
+ TabContentsContainer* source, |
+ const gfx::Rect& future_source_bounds, |
+ const gfx::Point& future_parent_offset) { |
+ gfx::Point resize_corner_origin(browser_reserved_rect.origin()); |
+ // Convert |resize_corner_origin| from browser_view_ to source's parent |
+ // coordinates. |
+ views::View::ConvertPointToView(browser_view_, source->GetParent(), |
+ &resize_corner_origin); |
+ // Create |reserved_rect| in source's parent coordinates. |
+ gfx::Rect reserved_rect(resize_corner_origin, browser_reserved_rect.size()); |
+ // Apply source's parent future offset to it. |
+ reserved_rect.Offset(-future_parent_offset.x(), -future_parent_offset.y()); |
+ if (future_source_bounds.Intersects(reserved_rect)) { |
+ // |source| is not properly positioned yet to use ConvertPointToView, |
+ // so convert it into |source|'s coordinates manually. |
+ reserved_rect.Offset(-future_source_bounds.x(), -future_source_bounds.y()); |
+ } else { |
+ reserved_rect = gfx::Rect(); |
+ } |
+ |
+ source->SetReservedContentsRect(reserved_rect); |
+} |
+ |
void BrowserViewLayout::LayoutTabContents(int top, int bottom) { |
- contents_split_->SetBounds(vertical_layout_rect_.x(), top, |
- vertical_layout_rect_.width(), bottom - top); |
+ // The ultimate idea is to calcualte bounds and reserved areas for all |
+ // contents views first and then resize them all, so every view |
+ // (and its contents) is resized and laid out only once. |
+ |
+ // The views hierarcy (see browser_view.h for more details): |
+ // 1) Sidebar is not allowed: |
+ // contents_split_ -> [contents_container_ | devtools] |
+ // 2) Sidebar is allowed: |
+ // contents_split_ -> |
+ // [sidebar_split -> [contents_container_ | sidebar]] | devtools |
+ |
+ gfx::Rect sidebar_split_bounds; |
+ gfx::Rect contents_bounds; |
+ gfx::Rect sidebar_bounds; |
+ gfx::Rect devtools_bounds; |
+ |
+ gfx::Rect contents_split_bounds(vertical_layout_rect_.x(), top, |
+ vertical_layout_rect_.width(), |
+ std::max(0, bottom - top)); |
+ contents_split_->CalculateChildrenBounds( |
+ contents_split_bounds, &sidebar_split_bounds, &devtools_bounds); |
+ gfx::Point contents_split_offset( |
+ contents_split_bounds.x() - contents_split_->bounds().x(), |
+ contents_split_bounds.y() - contents_split_->bounds().y()); |
+ gfx::Point sidebar_split_offset(contents_split_offset); |
+ sidebar_split_offset.Offset(sidebar_split_bounds.x(), |
+ sidebar_split_bounds.y()); |
+ |
+ views::SingleSplitView* sidebar_split = browser_view_->sidebar_split_; |
+ if (sidebar_split) { |
+ DCHECK(sidebar_split == contents_split_->GetChildViewAt(0)); |
+ sidebar_split->CalculateChildrenBounds( |
+ sidebar_split_bounds, &contents_bounds, &sidebar_bounds); |
+ } else { |
+ contents_bounds = sidebar_split_bounds; |
+ } |
+ |
+ // Layout resize corner, sidebar mini tabs and calculate reserved contents |
+ // rects here as all contents view bounds are already determined, but not yet |
+ // set at this point, so contents will be laid out once at most. |
+ // TODO(alekseys): layout sidebar minitabs and adjust reserved rect |
+ // accordingly. |
+ gfx::Rect browser_reserved_rect; |
+ if (!browser_view_->frame_->GetWindow()->IsMaximized() && |
+ !browser_view_->frame_->GetWindow()->IsFullscreen()) { |
+ gfx::Size resize_corner_size = browser_view_->GetResizeCornerSize(); |
+ if (!resize_corner_size.IsEmpty()) { |
+ gfx::Rect bounds = browser_view_->GetLocalBounds(false); |
+ gfx::Point resize_corner_origin( |
+ bounds.right() - resize_corner_size.width(), |
+ bounds.bottom() - resize_corner_size.height()); |
+ browser_reserved_rect = |
+ gfx::Rect(resize_corner_origin, resize_corner_size); |
+ } |
+ } |
+ |
+ UpdateReservedContentsRect(browser_reserved_rect, |
+ browser_view_->contents_container_, |
+ contents_bounds, |
+ sidebar_split_offset); |
+ if (sidebar_split) { |
+ UpdateReservedContentsRect(browser_reserved_rect, |
+ browser_view_->sidebar_container_, |
+ sidebar_bounds, |
+ sidebar_split_offset); |
+ } |
+ UpdateReservedContentsRect(browser_reserved_rect, |
+ browser_view_->devtools_container_, |
+ devtools_bounds, |
+ contents_split_offset); |
+ |
+ // Now it's safe to actually resize all contents views in the hierarchy. |
+ contents_split_->SetBounds(contents_split_bounds); |
+ if (sidebar_split) |
+ sidebar_split->SetBounds(sidebar_split_bounds); |
} |
int BrowserViewLayout::GetTopMarginForActiveContent() { |