diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.cc | 70 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view.h | 12 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view_layout.cc | 113 | ||||
-rw-r--r-- | chrome/browser/ui/views/frame/browser_view_layout.h | 16 | ||||
-rw-r--r-- | chrome/browser/ui/views/tab_contents/tab_contents_container.cc | 40 | ||||
-rw-r--r-- | chrome/browser/ui/views/tab_contents/tab_contents_container.h | 28 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 |
7 files changed, 182 insertions, 98 deletions
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 1993374..a52745b 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc @@ -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); @@ -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 { @@ -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()-> @@ -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))); @@ -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); @@ -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))); @@ -2102,7 +2070,8 @@ 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( @@ -2110,7 +2079,8 @@ void BrowserView::UpdateSidebarForContents(TabContentsWrapper* tab_contents) { sidebar_split_->width() - sidebar_split_->divider_offset()); sidebar_container_->SetVisible(false); - sidebar_split_->Layout(); + sidebar_split_->InvalidateLayout(); + Layout(); } } @@ -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( @@ -2157,7 +2128,8 @@ void BrowserView::UpdateDevToolsForContents(TabContentsWrapper* wrapper) { devtools_focus_tracker_->FocusLastFocusedExternalView(); devtools_container_->SetVisible(false); - contents_split_->Layout(); + contents_split_->InvalidateLayout(); + Layout(); } } @@ -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) { diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 79b0859..1825d64a 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h @@ -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" @@ -53,6 +54,7 @@ class InfoBarContainer; class LocationBarView; class SideTabStrip; class StatusBubbleViews; +class TabContentsContainer; class TabStripModel; class ToolbarView; class ZoomMenuModel; @@ -66,7 +68,6 @@ class JumpList; namespace views { class ExternalFocusTracker; class Menu; -class SingleSplitView; } /////////////////////////////////////////////////////////////////////////////// @@ -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[]; @@ -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 @@ -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_; diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc index 34549bd..6dc8cd0 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.cc +++ b/chrome/browser/ui/views/frame/browser_view_layout.cc @@ -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::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; @@ -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() { diff --git a/chrome/browser/ui/views/frame/browser_view_layout.h b/chrome/browser/ui/views/frame/browser_view_layout.h index 279803c..1b680a1 100644 --- a/chrome/browser/ui/views/frame/browser_view_layout.h +++ b/chrome/browser/ui/views/frame/browser_view_layout.h @@ -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: @@ -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); @@ -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_; diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_container.cc b/chrome/browser/ui/views/tab_contents/tab_contents_container.cc index 06c3400..90af997 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_container.cc +++ b/chrome/browser/ui/views/tab_contents/tab_contents_container.cc @@ -25,8 +25,7 @@ TabContentsContainer::TabContentsContainer() : native_container_(NULL), - tab_contents_(NULL), - reserved_area_delegate_(NULL) { + tab_contents_(NULL) { SetID(VIEW_ID_TAB_CONTAINER); } @@ -46,9 +45,6 @@ void TabContentsContainer::ChangeTabContents(TabContents* contents) { tab_contents_->WasHidden(); RemoveObservers(); } -#if !defined(TOUCH_UI) - TabContents* old_contents = tab_contents_; -#endif tab_contents_ = contents; // When detaching the last tab of the browser ChangeTabContents is invoked // with NULL. Don't attempt to do anything in that case. @@ -63,9 +59,7 @@ void TabContentsContainer::ChangeTabContents(TabContents* contents) { Layout(); } #else - RenderWidgetHostViewChanged( - old_contents ? old_contents->GetRenderWidgetHostView() : NULL, - tab_contents_->GetRenderWidgetHostView()); + RenderWidgetHostViewChanged(tab_contents_->GetRenderWidgetHostView()); native_container_->AttachContents(tab_contents_); #endif AddObservers(); @@ -82,6 +76,17 @@ void TabContentsContainer::SetFastResize(bool fast_resize) { native_container_->SetFastResize(fast_resize); } +void TabContentsContainer::SetReservedContentsRect( + const gfx::Rect& reserved_rect) { + cached_reserved_rect_ = reserved_rect; +#if !defined(TOUCH_UI) + if (tab_contents_ && tab_contents_->GetRenderWidgetHostView()) { + tab_contents_->GetRenderWidgetHostView()->set_reserved_contents_rect( + reserved_rect); + } +#endif +} + //////////////////////////////////////////////////////////////////////////////// // TabContentsContainer, NotificationObserver implementation: @@ -108,8 +113,6 @@ void TabContentsContainer::Layout() { views::View::Layout(); #else if (native_container_) { - if (reserved_area_delegate_) - reserved_area_delegate_->UpdateReservedContentsRect(this); native_container_->GetView()->SetBounds(0, 0, width(), height()); native_container_->GetView()->Layout(); } @@ -158,10 +161,8 @@ void TabContentsContainer::RenderViewHostChanged(RenderViewHost* old_host, #if defined(TOUCH_UI) NOTIMPLEMENTED(); // TODO(anicolao) #else - if (new_host) { - RenderWidgetHostViewChanged( - old_host ? old_host->view() : NULL, new_host->view()); - } + if (new_host) + RenderWidgetHostViewChanged(new_host->view()); native_container_->RenderViewHostChanged(old_host, new_host); #endif } @@ -174,12 +175,7 @@ void TabContentsContainer::TabContentsDestroyed(TabContents* contents) { } void TabContentsContainer::RenderWidgetHostViewChanged( - RenderWidgetHostView* old_view, RenderWidgetHostView* new_view) { - // Carry over the reserved rect, if possible. - if (old_view && new_view) { - new_view->set_reserved_contents_rect(old_view->reserved_contents_rect()); - } else { - if (reserved_area_delegate_) - reserved_area_delegate_->UpdateReservedContentsRect(this); - } + RenderWidgetHostView* new_view) { + if (new_view) + new_view->set_reserved_contents_rect(cached_reserved_rect_); } diff --git a/chrome/browser/ui/views/tab_contents/tab_contents_container.h b/chrome/browser/ui/views/tab_contents/tab_contents_container.h index 83633e8..1ba30ed 100644 --- a/chrome/browser/ui/views/tab_contents/tab_contents_container.h +++ b/chrome/browser/ui/views/tab_contents/tab_contents_container.h @@ -19,19 +19,6 @@ class TabContents; class TabContentsContainer : public views::View, public NotificationObserver { public: - // Interface to request the reserved contents area updates. - class ReservedAreaDelegate { - public: - // Notifies that |source|'s reserved contents area should be updated. - // Reserved contents area is a rect in tab contents view coordinates where - // contents should not be rendered (to display the resize corner, sidebar - // mini tabs or any other UI elements overlaying this container). - virtual void UpdateReservedContentsRect( - const TabContentsContainer* source) = 0; - protected: - virtual ~ReservedAreaDelegate() {} - }; - TabContentsContainer(); virtual ~TabContentsContainer(); @@ -50,9 +37,9 @@ class TabContentsContainer : public views::View, // so performance is better. void SetFastResize(bool fast_resize); - void set_reserved_area_delegate(ReservedAreaDelegate* delegate) { - reserved_area_delegate_ = delegate; - } + // Updates the current reserved rect in view coordinates where contents + // should not be rendered to draw the resize corner, sidebar mini tabs etc. + void SetReservedContentsRect(const gfx::Rect& reserved_rect); // Overridden from NotificationObserver: virtual void Observe(NotificationType type, @@ -84,8 +71,7 @@ class TabContentsContainer : public views::View, void TabContentsDestroyed(TabContents* contents); // Called when the RenderWidgetHostView of the hosted TabContents has changed. - void RenderWidgetHostViewChanged(RenderWidgetHostView* old_view, - RenderWidgetHostView* new_view); + void RenderWidgetHostViewChanged(RenderWidgetHostView* new_view); // An instance of a NativeTabContentsContainer object that holds the native // view handle associated with the attached TabContents. @@ -97,8 +83,10 @@ class TabContentsContainer : public views::View, // Handles registering for our notifications. NotificationRegistrar registrar_; - // Delegate for enquiring reserved contents area. Not owned by us. - ReservedAreaDelegate* reserved_area_delegate_; + // The current reserved rect in view coordinates where contents should not be + // rendered to draw the resize corner, sidebar mini tabs etc. + // Cached here to update ever changing renderers. + gfx::Rect cached_reserved_rect_; DISALLOW_COPY_AND_ASSIGN(TabContentsContainer); }; diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 0f48b85..a0e0a99 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1722,6 +1722,7 @@ '../views/box_layout_unittest.cc', '../views/controls/label_unittest.cc', '../views/controls/progress_bar_unittest.cc', + '../views/controls/single_split_view.cc', '../views/controls/tabbed_pane/tabbed_pane_unittest.cc', '../views/controls/table/table_view_unittest.cc', '../views/controls/textfield/textfield_views_model_unittest.cc', |