Skip to content

Commit

Permalink
Streamline the layout of the BrowserView's children TabContents views.
Browse files Browse the repository at this point in the history
Modify SingleSplitView to calculate its children view's bounds, but do not actually resize them
and change BrowserViewLayout accordingly (BrowserViewLayout resizes all views now).
Do all reserved contents rect calculations before resizing TabContents views.

Rationale: to do all BrowserView layout related actions in the context of
BrowserViewLayout::Layout call and to minimize actual contents re-layouts.

BUG=51084
TEST=All tests should pass

Review URL: http://codereview.chromium.org/5606012

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71230 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
alekseys@chromium.org committed Jan 12, 2011
1 parent c8fd6c6 commit 84f024c
Show file tree
Hide file tree
Showing 12 changed files with 510 additions and 157 deletions.
70 changes: 23 additions & 47 deletions chrome/browser/ui/views/frame/browser_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1348,10 +1348,8 @@ void BrowserView::PrepareForInstant() {
}

void BrowserView::ShowInstant(TabContents* preview_contents) {
if (!preview_container_) {
if (!preview_container_)
preview_container_ = new TabContentsContainer();
preview_container_->set_reserved_area_delegate(this);
}
contents_->SetPreview(preview_container_, preview_contents);
preview_container_->ChangeTabContents(preview_contents);

Expand Down Expand Up @@ -1825,41 +1823,12 @@ void BrowserView::InfoBarSizeChanged(bool is_animating) {
SelectedTabToolbarSizeChanged(is_animating);
}

void BrowserView::UpdateReservedContentsRect(
const TabContentsContainer* source) {
RenderWidgetHostView* render_widget_host_view =
source->tab_contents() ? source->tab_contents()->GetRenderWidgetHostView()
: NULL;
if (!render_widget_host_view)
return;

gfx::Rect reserved_rect;

if (!frame_->GetWindow()->IsMaximized() &&
!frame_->GetWindow()->IsFullscreen()) {
gfx::Size resize_corner_size = ResizeCorner::GetSize();
if (!resize_corner_size.IsEmpty()) {
gfx::Point resize_corner_origin;
gfx::Rect bounds = GetLocalBounds(false);
resize_corner_origin.set_x(bounds.right() - resize_corner_size.width());
resize_corner_origin.set_y(bounds.bottom() - resize_corner_size.height());

View::ConvertPointToView(this, source, &resize_corner_origin);

gfx::Size container_size = source->size();

if (resize_corner_origin.x() < container_size.width() &&
resize_corner_origin.y() < container_size.height()) {
reserved_rect = gfx::Rect(resize_corner_origin, resize_corner_size);
}
}
}

// TODO(alekseys): for source == contents_container_, consult SidebarTabView
// for the current size to reserve. Something like this:
// reserved_rect = reserved_rect.Union(SidebarTabView::GetCurrentBounds());

render_widget_host_view->set_reserved_contents_rect(reserved_rect);
bool BrowserView::SplitHandleMoved(views::SingleSplitView* view) {
for (int i = 0; i < view->GetChildViewCount(); ++i)
view->GetChildViewAt(i)->InvalidateLayout();
SchedulePaint();
Layout();
return false;
}

views::LayoutManager* BrowserView::CreateLayoutManager() const {
Expand Down Expand Up @@ -1922,7 +1891,6 @@ void BrowserView::Init() {
AddChildView(infobar_container_);

contents_container_ = new TabContentsContainer;
contents_container_->set_reserved_area_delegate(this);
contents_ = new ContentsContainer(contents_container_);

SkColor bg_color = GetWidget()->GetThemeProvider()->
Expand All @@ -1931,14 +1899,14 @@ void BrowserView::Init() {
bool sidebar_allowed = SidebarManager::IsSidebarAllowed();
if (sidebar_allowed) {
sidebar_container_ = new TabContentsContainer;
sidebar_container_->set_reserved_area_delegate(this);
sidebar_container_->SetID(VIEW_ID_SIDE_BAR_CONTAINER);
sidebar_container_->SetVisible(false);

sidebar_split_ = new views::SingleSplitView(
contents_,
sidebar_container_,
views::SingleSplitView::HORIZONTAL_SPLIT);
views::SingleSplitView::HORIZONTAL_SPLIT,
this);
sidebar_split_->SetID(VIEW_ID_SIDE_BAR_SPLIT);
sidebar_split_->SetAccessibleName(
UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_SIDE_BAR)));
Expand All @@ -1947,7 +1915,6 @@ void BrowserView::Init() {
}

devtools_container_ = new TabContentsContainer;
devtools_container_->set_reserved_area_delegate(this);
devtools_container_->SetID(VIEW_ID_DEV_TOOLS_DOCKED);
devtools_container_->SetVisible(false);

Expand All @@ -1958,7 +1925,8 @@ void BrowserView::Init() {
contents_split_ = new views::SingleSplitView(
contents_view,
devtools_container_,
views::SingleSplitView::VERTICAL_SPLIT);
views::SingleSplitView::VERTICAL_SPLIT,
this);
contents_split_->SetID(VIEW_ID_CONTENTS_SPLIT);
contents_split_->SetAccessibleName(
UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_WEB_CONTENTS)));
Expand Down Expand Up @@ -2102,15 +2070,17 @@ void BrowserView::UpdateSidebarForContents(TabContentsWrapper* tab_contents) {
sidebar_split_->width() - sidebar_width);

sidebar_container_->SetVisible(true);
sidebar_split_->Layout();
sidebar_split_->InvalidateLayout();
Layout();
} else if (should_hide) {
// Store split offset when hiding sidebar only.
g_browser_process->local_state()->SetInteger(
prefs::kExtensionSidebarWidth,
sidebar_split_->width() - sidebar_split_->divider_offset());

sidebar_container_->SetVisible(false);
sidebar_split_->Layout();
sidebar_split_->InvalidateLayout();
Layout();
}
}

Expand Down Expand Up @@ -2147,7 +2117,8 @@ void BrowserView::UpdateDevToolsForContents(TabContentsWrapper* wrapper) {
contents_split_->set_divider_offset(split_offset);

devtools_container_->SetVisible(true);
contents_split_->Layout();
contents_split_->InvalidateLayout();
Layout();
} else if (should_hide) {
// Store split offset when hiding devtools window only.
g_browser_process->local_state()->SetInteger(
Expand All @@ -2157,7 +2128,8 @@ void BrowserView::UpdateDevToolsForContents(TabContentsWrapper* wrapper) {
devtools_focus_tracker_->FocusLastFocusedExternalView();

devtools_container_->SetVisible(false);
contents_split_->Layout();
contents_split_->InvalidateLayout();
Layout();
}
}

Expand Down Expand Up @@ -2567,6 +2539,10 @@ void BrowserView::ProcessTabSelected(TabContentsWrapper* new_contents,
UpdateUIForContents(new_contents);
}

gfx::Size BrowserView::GetResizeCornerSize() const {
return ResizeCorner::GetSize();
}

#if !defined(OS_CHROMEOS)
// static
BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
Expand Down
12 changes: 8 additions & 4 deletions chrome/browser/ui/views/frame/browser_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "chrome/browser/ui/views/unhandled_keyboard_event_handler.h"
#include "chrome/common/notification_registrar.h"
#include "gfx/native_widget_types.h"
#include "views/controls/single_split_view.h"
#include "views/window/client_view.h"
#include "views/window/window_delegate.h"

Expand Down Expand Up @@ -53,6 +54,7 @@ class InfoBarContainer;
class LocationBarView;
class SideTabStrip;
class StatusBubbleViews;
class TabContentsContainer;
class TabStripModel;
class ToolbarView;
class ZoomMenuModel;
Expand All @@ -66,7 +68,6 @@ class JumpList;
namespace views {
class ExternalFocusTracker;
class Menu;
class SingleSplitView;
}

///////////////////////////////////////////////////////////////////////////////
Expand All @@ -84,7 +85,7 @@ class BrowserView : public BrowserBubbleHost,
public views::WindowDelegate,
public views::ClientView,
public InfoBarContainer::Delegate,
public TabContentsContainer::ReservedAreaDelegate {
public views::SingleSplitView::Observer {
public:
// The browser view's class name.
static const char kViewClassName[];
Expand Down Expand Up @@ -396,8 +397,8 @@ class BrowserView : public BrowserBubbleHost,
// InfoBarContainer::Delegate overrides
virtual void InfoBarSizeChanged(bool is_animating);

// TabContentsContainer::ReservedAreaDelegate overrides.
virtual void UpdateReservedContentsRect(const TabContentsContainer* source);
// views::SingleSplitView::Observer overrides:
virtual bool SplitHandleMoved(views::SingleSplitView* view);

protected:
// Appends to |toolbars| a pointer to each AccessiblePaneView that
Expand Down Expand Up @@ -522,6 +523,9 @@ class BrowserView : public BrowserBubbleHost,
void ProcessTabSelected(TabContentsWrapper* new_contents,
bool change_tab_contents);

// Exposes resize corner size to BrowserViewLayout.
gfx::Size GetResizeCornerSize() const;

// Last focused view that issued a tab traversal.
int last_focused_view_storage_id_;

Expand Down
113 changes: 109 additions & 4 deletions chrome/browser/ui/views/frame/browser_view_layout.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -207,9 +209,9 @@ void BrowserViewLayout::Uninstalled(views::View* host) {}
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;
Expand Down Expand Up @@ -363,9 +365,112 @@ int BrowserViewLayout::LayoutInfoBar(int top) {
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() {
Expand Down
16 changes: 15 additions & 1 deletion chrome/browser/ui/views/frame/browser_view_layout.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@ class Browser;
class BrowserView;
class ContentsContainer;
class DownloadShelfView;
class TabContentsContainer;
class ToolbarView;

namespace views {
class SingleSplitView;
}

// The layout manager used in chrome browser.
class BrowserViewLayout : public views::LayoutManager {
public:
Expand Down Expand Up @@ -61,6 +66,15 @@ class BrowserViewLayout : public views::LayoutManager {
int LayoutBookmarkBar(int top);
int LayoutInfoBar(int top);

// Updates |source|'s reserved contents rect by mapping BrowserView's
// |browser_reserved_rect| into |future_source_bounds| taking into
// account |source|'s |future_parent_offset| (offset is relative to
// browser_view_).
void UpdateReservedContentsRect(const gfx::Rect& browser_reserved_rect,
TabContentsContainer* source,
const gfx::Rect& future_source_bounds,
const gfx::Point& future_parent_offset);

// Layout the TabContents container, between the coordinates |top| and
// |bottom|.
void LayoutTabContents(int top, int bottom);
Expand Down Expand Up @@ -88,7 +102,7 @@ class BrowserViewLayout : public views::LayoutManager {
// Child views that the layout manager manages.
BaseTabStrip* tabstrip_;
ToolbarView* toolbar_;
views::View* contents_split_;
views::SingleSplitView* contents_split_;
ContentsContainer* contents_container_;
views::View* infobar_container_;
DownloadShelfView* download_shelf_;
Expand Down
Loading

0 comments on commit 84f024c

Please sign in to comment.