| Index: chrome/browser/ui/views/frame/browser_view.cc
|
| diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
|
| index b5c17fb15e71e9b7e202041aa9628d64a321b239..86a0d87ec4a996ca14cb44801792b1508c6d6d53 100644
|
| --- a/chrome/browser/ui/views/frame/browser_view.cc
|
| +++ b/chrome/browser/ui/views/frame/browser_view.cc
|
| @@ -34,6 +34,8 @@
|
| #include "chrome/browser/search/search.h"
|
| #include "chrome/browser/sessions/tab_restore_service.h"
|
| #include "chrome/browser/sessions/tab_restore_service_factory.h"
|
| +#include "chrome/browser/sidebar/sidebar_container.h"
|
| +#include "chrome/browser/sidebar/sidebar_manager.h"
|
| #include "chrome/browser/signin/signin_header_helper.h"
|
| #include "chrome/browser/themes/theme_properties.h"
|
| #include "chrome/browser/themes/theme_service_factory.h"
|
| @@ -131,10 +133,13 @@
|
| #include "ui/gfx/screen.h"
|
| #include "ui/strings/grit/ui_strings.h"
|
| #include "ui/views/controls/button/menu_button.h"
|
| +#include "ui/views/controls/single_split_view.h"
|
| +#include "ui/views/controls/single_split_view_listener.h"
|
| #include "ui/views/controls/textfield/textfield.h"
|
| #include "ui/views/controls/webview/webview.h"
|
| #include "ui/views/focus/external_focus_tracker.h"
|
| #include "ui/views/focus/view_storage.h"
|
| +#include "ui/views/layout/box_layout.h"
|
| #include "ui/views/layout/grid_layout.h"
|
| #include "ui/views/widget/native_widget.h"
|
| #include "ui/views/widget/root_view.h"
|
| @@ -463,6 +468,9 @@ BrowserView::BrowserView()
|
| #endif
|
| force_location_bar_focus_(false),
|
| activate_modal_dialog_factory_(this) {
|
| + registrar_.Add(
|
| + this, chrome::NOTIFICATION_SIDEBAR_CHANGED,
|
| + content::Source<SidebarManager>(SidebarManager::GetInstance()));
|
| }
|
|
|
| BrowserView::~BrowserView() {
|
| @@ -540,6 +548,14 @@ void BrowserView::InitStatusBubble() {
|
| contents_web_view_->SetStatusBubble(status_bubble_.get());
|
| }
|
|
|
| +bool BrowserView::SplitHandleMoved(views::SingleSplitView* sender) {
|
| + for (int i = 0; i < sender->child_count(); ++i)
|
| + sender->child_at(i)->InvalidateLayout();
|
| + SchedulePaint();
|
| + Layout();
|
| + return false;
|
| +}
|
| +
|
| gfx::Rect BrowserView::GetToolbarBounds() const {
|
| gfx::Rect toolbar_bounds(toolbar_->bounds());
|
| if (toolbar_bounds.IsEmpty())
|
| @@ -654,6 +670,22 @@ gfx::ImageSkia BrowserView::GetOTRAvatarIcon() const {
|
| return *GetThemeProvider()->GetImageSkiaNamed(IDR_OTR_ICON);
|
| }
|
|
|
| +void BrowserView::Observe(int type,
|
| + const content::NotificationSource& source,
|
| + const content::NotificationDetails& details) {
|
| + content::WebContents* target =
|
| + content::Details<SidebarContainer>(details)->web_contents();
|
| + switch (type) {
|
| + case chrome::NOTIFICATION_SIDEBAR_CHANGED:
|
| + if (GetActiveWebContents() == target)
|
| + UpdateSidebarForContents(target);
|
| + break;
|
| + default:
|
| + NOTREACHED(); // we don't ask for anything else!
|
| + break;
|
| + }
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
| // BrowserView, BrowserWindow implementation:
|
|
|
| @@ -883,6 +915,7 @@ void BrowserView::OnActiveTabChanged(content::WebContents* old_contents,
|
| // to avoid toggling the size of any of them.
|
| UpdateDevToolsForContents(new_contents, !change_tab_contents);
|
|
|
| + UpdateSidebarForContents(new_contents);
|
| if (change_tab_contents) {
|
| web_contents_close_handler_->ActiveTabChanged();
|
| contents_web_view_->SetWebContents(new_contents);
|
| @@ -1311,6 +1344,12 @@ void BrowserView::ShowOneClickSigninBubble(
|
| }
|
| #endif
|
|
|
| +int BrowserView::GetSidebarWidth() const {
|
| + if (!sidebar_container_ || !sidebar_container_->visible())
|
| + return 0;
|
| + return sidebar_split_->divider_offset();
|
| +}
|
| +
|
| void BrowserView::SetDownloadShelfVisible(bool visible) {
|
| // This can be called from the superclass destructor, when it destroys our
|
| // child views. At that point, browser_ is already gone.
|
| @@ -1564,6 +1603,7 @@ void BrowserView::TabDetachedAt(WebContents* contents, int index) {
|
| infobar_container_->ChangeInfoBarManager(nullptr);
|
| UpdateDevToolsForContents(nullptr, true);
|
| }
|
| + UpdateSidebarForContents(NULL);
|
| }
|
|
|
| void BrowserView::TabDeactivated(WebContents* contents) {
|
| @@ -2042,8 +2082,27 @@ void BrowserView::InitViews() {
|
| contents_container_->AddChildView(contents_web_view_);
|
| contents_container_->SetLayoutManager(new ContentsLayoutManager(
|
| devtools_web_view_, contents_web_view_));
|
| - AddChildView(contents_container_);
|
| - set_contents_view(contents_container_);
|
| +
|
| + sidebar_web_view_ = new views::WebView(browser_->profile());
|
| + sidebar_web_view_->set_id(VIEW_ID_SIDE_BAR_VIEW);
|
| + sidebar_web_view_->SetVisible(false);
|
| +
|
| + sidebar_container_ = new views::View();
|
| + sidebar_container_->AddChildView(sidebar_web_view_);
|
| + sidebar_container_->set_id(VIEW_ID_SIDE_BAR_CONTAINER);
|
| + sidebar_container_->SetVisible(false);
|
| +
|
| + sidebar_split_ = new views::SingleSplitView(
|
| + contents_container_, sidebar_container_,
|
| + views::SingleSplitView::HORIZONTAL_SPLIT, this);
|
| +
|
| + sidebar_split_->set_id(VIEW_ID_SIDE_BAR_SPLIT);
|
| + sidebar_split_->set_background(views::Background::CreateSolidBackground(
|
| + GetWidget()->GetThemeProvider()->GetColor(
|
| + ThemeProperties::COLOR_TOOLBAR)));
|
| + sidebar_split_->set_resize_leading_on_bounds_change(false);
|
| + AddChildView(sidebar_split_);
|
| + set_contents_view(sidebar_split_);
|
|
|
| // Top container holds tab strip and toolbar and lives at the front of the
|
| // view hierarchy.
|
| @@ -2072,16 +2131,10 @@ void BrowserView::InitViews() {
|
| immersive_mode_controller_->Init(this);
|
|
|
| BrowserViewLayout* browser_view_layout = new BrowserViewLayout;
|
| - browser_view_layout->Init(new BrowserViewLayoutDelegateImpl(this),
|
| - browser(),
|
| - this,
|
| - top_container_,
|
| - tabstrip_,
|
| - toolbar_,
|
| - infobar_container_,
|
| - contents_container_,
|
| - GetContentsLayoutManager(),
|
| - immersive_mode_controller_.get());
|
| + browser_view_layout->Init(
|
| + new BrowserViewLayoutDelegateImpl(this), browser(), this, top_container_,
|
| + tabstrip_, toolbar_, infobar_container_, sidebar_split_,
|
| + GetContentsLayoutManager(), immersive_mode_controller_.get());
|
| SetLayoutManager(browser_view_layout);
|
|
|
| #if defined(OS_WIN)
|
| @@ -2095,6 +2148,67 @@ void BrowserView::InitViews() {
|
| GetLocationBar()->GetOmniboxView()->model()->popup_model()->AddObserver(this);
|
| }
|
|
|
| +void BrowserView::UpdateSidebarForContents(content::WebContents* new_contents) {
|
| + if (!sidebar_container_)
|
| + return; // Happens when sidebar is not allowed.
|
| + if (!SidebarManager::GetInstance())
|
| + return; // Happens only in tests.s
|
| +
|
| + WebContents* sidebar_contents = NULL;
|
| + if (new_contents) {
|
| + SidebarContainer* client_host =
|
| + SidebarManager::GetInstance()->GetActiveSidebarContainerFor(
|
| + new_contents);
|
| + if (client_host)
|
| + sidebar_contents = client_host->host_contents();
|
| + }
|
| +
|
| + bool visible = NULL != sidebar_contents;
|
| +
|
| + bool should_show = visible && !sidebar_container_->visible();
|
| + bool should_hide = !visible && sidebar_container_->visible();
|
| +
|
| + // Update sidebar content.
|
| + WebContents* old_contents =
|
| + static_cast<WebContents*>(sidebar_web_view_->web_contents());
|
| +
|
| + sidebar_web_view_->SetWebContents(sidebar_contents);
|
| +
|
| + SidebarManager::GetInstance()->NotifyStateChanges(old_contents,
|
| + sidebar_contents);
|
| +
|
| + // Update sidebar UI width.
|
| + if (should_show) {
|
| + // Restore split offset.
|
| + int sidebar_width = g_browser_process->local_state()->GetInteger(
|
| + prefs::kExtensionSidebarWidth);
|
| + if (sidebar_width < 0) {
|
| + // By default sidebar width is 1/7th of the current page content width.
|
| + sidebar_width = sidebar_split_->width() / 7;
|
| + }
|
| + int min_sidebar_width = sidebar_split_->GetMinimumSize().width();
|
| + // Not allowed to be wider than 50% of the split-view's frame
|
| + sidebar_width = std::min(sidebar_split_->width() / 2 - min_sidebar_width,
|
| + std::max(min_sidebar_width, sidebar_width));
|
| + sidebar_split_->set_divider_offset(sidebar_split_->width() - sidebar_width);
|
| +
|
| + sidebar_container_->SetVisible(true);
|
| + sidebar_web_view_->SetVisible(true);
|
| + 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_->InvalidateLayout();
|
| + Layout();
|
| + }
|
| +}
|
| +
|
| void BrowserView::LoadingAnimationCallback() {
|
| base::TimeTicks now = base::TimeTicks::Now();
|
| if (!last_animation_time_.is_null()) {
|
|
|