Index: chrome/browser/ui/views/frame/browser_view_layout.cc |
=================================================================== |
--- chrome/browser/ui/views/frame/browser_view_layout.cc (revision 74134) |
+++ chrome/browser/ui/views/frame/browser_view_layout.cc (working copy) |
@@ -7,6 +7,8 @@ |
#include "chrome/browser/sidebar/sidebar_manager.h" |
#include "chrome/browser/ui/find_bar/find_bar.h" |
#include "chrome/browser/ui/find_bar/find_bar_controller.h" |
+#include "chrome/browser/ui/views/sidebar/sidebar_base_tab_strip.h" |
+#include "chrome/browser/ui/views/sidebar/sidebar_tab_strip_host.h" |
#include "chrome/browser/ui/view_ids.h" |
#include "chrome/browser/ui/views/bookmark_bar_view.h" |
#include "chrome/browser/ui/views/download_shelf_view.h" |
@@ -261,7 +263,7 @@ |
int active_top_margin = GetTopMarginForActiveContent(); |
top -= active_top_margin; |
contents_container_->SetActiveTopMargin(active_top_margin); |
- LayoutTabContents(top, bottom); |
+ LayoutTabContents(top, bottom, active_top_margin); |
// This must be done _after_ we lay out the TabContents since this |
// code calls back into us to find the bounding box the find bar |
// must be laid out within, and that code depends on the |
@@ -355,9 +357,29 @@ |
int bookmark_bar_height = active_bookmark_bar_->GetPreferredSize().height(); |
y -= kSeparationLineHeight + active_bookmark_bar_->GetToolbarOverlap(false); |
active_bookmark_bar_->SetVisible(true); |
- active_bookmark_bar_->SetBounds(vertical_layout_rect_.x(), y, |
- vertical_layout_rect_.width(), |
- bookmark_bar_height); |
+ int bookmark_bar_width = vertical_layout_rect_.width(); |
+ int bookmark_bar_left = vertical_layout_rect_.x(); |
+ // When bookmark bar is detached and sidebar is there, make bookmark bar |
+ // of the same witdth as page contents to keep the illusion that bookmark |
+ // bar is a part of NewTabPage. |
+ if (active_bookmark_bar_->IsDetached() && browser_view_->sidebar_split_) { |
+ gfx::Rect sidebar_split_bounds(vertical_layout_rect_.x(), top, |
+ vertical_layout_rect_.width(), |
+ vertical_layout_rect_.height()); |
+ gfx::Rect contents_bounds; |
+ gfx::Rect sidebar_bounds; |
+ browser_view_->sidebar_split_->CalculateChildrenBounds( |
+ sidebar_split_bounds, &contents_bounds, &sidebar_bounds); |
+ // Sidebar ought to stay on the right side of the browser window, |
+ // where web page scrollbar is rendered. |
+ if (base::i18n::IsRTL()) |
+ std::swap(contents_bounds, sidebar_bounds); |
+ bookmark_bar_width = contents_bounds.width(); |
+ if (base::i18n::IsRTL()) |
+ bookmark_bar_left = vertical_layout_rect_.width() - bookmark_bar_width; |
+ } |
+ active_bookmark_bar_->SetBounds(bookmark_bar_left, y, |
+ bookmark_bar_width, bookmark_bar_height); |
return y + bookmark_bar_height; |
} |
@@ -380,27 +402,37 @@ |
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(); |
+ gfx::Rect reserved_rect; |
+ if (!browser_reserved_rect.IsEmpty()) { |
+ 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. |
+ reserved_rect.set_origin(resize_corner_origin); |
+ reserved_rect.set_size(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()); |
+ // Convert it into renderer coordinate system. |
+ if (base::i18n::IsRTL()) { |
+ reserved_rect.set_x(future_source_bounds.width() - reserved_rect.x() - |
+ reserved_rect.width()); |
+ } |
+ } else { |
+ reserved_rect = gfx::Rect(); |
+ } |
} |
- |
source->SetReservedContentsRect(reserved_rect); |
} |
-void BrowserViewLayout::LayoutTabContents(int top, int bottom) { |
+void BrowserViewLayout::LayoutTabContents( |
+ int top, int bottom, int active_top_margin) { |
// 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. |
@@ -417,14 +449,18 @@ |
gfx::Rect sidebar_bounds; |
gfx::Rect devtools_bounds; |
+ // Calculate contents area, where the actual page, devtools and sidebar live. |
gfx::Rect contents_split_bounds(vertical_layout_rect_.x(), top, |
vertical_layout_rect_.width(), |
std::max(0, bottom - top)); |
+ // Calculate future page, devtools and sidebar contents bounds. |
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()); |
+ // Note that sidebar_split_offset is relative to browser_view_, |
+ // not to sidebar_split parent view. |
gfx::Point sidebar_split_offset(contents_split_offset); |
sidebar_split_offset.Offset(sidebar_split_bounds.x(), |
sidebar_split_bounds.y()); |
@@ -434,6 +470,10 @@ |
DCHECK(sidebar_split == contents_split_->GetChildViewAt(0)); |
sidebar_split->CalculateChildrenBounds( |
sidebar_split_bounds, &contents_bounds, &sidebar_bounds); |
+ // Sidebar ought to stay on the right side of the browser window, |
+ // where web page scrollbar is rendered. |
+ if (base::i18n::IsRTL()) |
+ std::swap(contents_bounds, sidebar_bounds); |
} else { |
contents_bounds = sidebar_split_bounds; |
} |
@@ -441,31 +481,84 @@ |
// 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(); |
+ int resize_corner_left = base::i18n::IsRTL() ? |
+ 0 : (bounds.right() - resize_corner_size.width()); |
gfx::Point resize_corner_origin( |
- bounds.right() - resize_corner_size.width(), |
+ resize_corner_left, |
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); |
+ // Layout sidebar minitabs. |
+ gfx::Rect sidebar_minitabs_browser_rect; |
+ if (browser_view_->sidebar_tabstrip_host_.get()) { |
+ gfx::Size tabstrip_size( |
+ browser_view_->sidebar_tabstrip_host_->GetContentsSize()); |
+ |
+ // Position mini tabs relative to sidebar split and manually adjust |
+ // for its future offset, since sidebar split bounds are not yet set. |
+ gfx::Point topleft; |
+ if (base::i18n::IsRTL()) { |
+ topleft = sidebar_bounds.IsEmpty() ? |
+ gfx::Point(contents_bounds.x() - 1, contents_bounds.bottom()) : |
+ gfx::Point(sidebar_bounds.x() + sidebar_bounds.width(), |
+ sidebar_bounds.bottom()); |
+ } else { |
+ topleft = sidebar_bounds.IsEmpty() ? |
+ gfx::Point(contents_bounds.right() - tabstrip_size.width() + 1, |
+ contents_bounds.bottom()) : |
+ gfx::Point(sidebar_bounds.x() - tabstrip_size.width(), |
+ sidebar_bounds.bottom()); |
+ } |
+ topleft.Offset(0, -tabstrip_size.height()); |
+ |
+ // Convert it to browser_view_ coordinates. Do it manually since the views |
+ // are not positioned yet, does the same job as |
+ // views::View::ConvertPointToView(sidebar_split, browser_view_, &topleft) |
+ topleft.Offset(sidebar_split_offset.x() + sidebar_split_bounds.x() + |
+ contents_split_bounds.x(), |
+ sidebar_split_offset.y() + sidebar_split_bounds.y() + |
+ contents_split_bounds.y()); |
+ |
+ sidebar_minitabs_browser_rect.set_origin(topleft); |
+ sidebar_minitabs_browser_rect.set_size(tabstrip_size); |
+ |
+ // Check whether mini tabs conflict with resize corner, and if so, |
+ // position them on top of the resize corner (move them up a bit). |
+ if (sidebar_minitabs_browser_rect.Intersects(browser_reserved_rect)) { |
+ topleft.set_y( |
+ browser_reserved_rect.y() - sidebar_minitabs_browser_rect.height()); |
+ sidebar_minitabs_browser_rect.set_y(topleft.y()); |
+ } |
+ |
+ // Adjust mini tabs host widget position. |
+ topleft.set_x(browser_view_->GetMirroredXWithWidthInView( |
+ topleft.x(), sidebar_minitabs_browser_rect.width())); |
+ views::View::ConvertPointToWidget(browser_view_, &topleft); |
+ browser_view_->sidebar_tabstrip_host_->SetPosition( |
+ gfx::Rect(topleft, tabstrip_size)); |
+ } |
+ |
+ // Update reserved rects for all containers. |
+ UpdateReservedContentsRect( |
+ browser_reserved_rect.Union(sidebar_minitabs_browser_rect), |
+ browser_view_->contents_container_, |
+ contents_bounds, |
+ sidebar_split_offset.Add(gfx::Point(0, active_top_margin))); |
if (sidebar_split) { |
- UpdateReservedContentsRect(browser_reserved_rect, |
- browser_view_->sidebar_container_, |
- sidebar_bounds, |
- sidebar_split_offset); |
+ UpdateReservedContentsRect( |
+ browser_reserved_rect.Union(sidebar_minitabs_browser_rect), |
+ browser_view_->sidebar_container_, |
+ sidebar_bounds, |
+ sidebar_split_offset); |
} |
UpdateReservedContentsRect(browser_reserved_rect, |
browser_view_->devtools_container_, |
@@ -483,18 +576,6 @@ |
!active_bookmark_bar_->IsDetached()) { |
return 0; |
} |
- |
- if (contents_split_->GetChildViewAt(1) && |
- contents_split_->GetChildViewAt(1)->IsVisible()) |
- return 0; |
- |
- if (SidebarManager::IsSidebarAllowed()) { |
- views::View* sidebar_split = contents_split_->GetChildViewAt(0); |
- if (sidebar_split->GetChildViewAt(1) && |
- sidebar_split->GetChildViewAt(1)->IsVisible()) |
- return 0; |
- } |
- |
// Adjust for separator. |
return active_bookmark_bar_->height() - kSeparationLineHeight; |
} |