diff options
Diffstat (limited to 'chrome/browser/views/frame/browser_view.cc')
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 155 |
1 files changed, 137 insertions, 18 deletions
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 1e32b5c..16dd49a 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -32,6 +32,8 @@ #include "chrome/browser/pref_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/sessions/tab_restore_service.h" +#include "chrome/browser/sidebar/sidebar_container.h" +#include "chrome/browser/sidebar/sidebar_manager.h" #include "chrome/browser/tab_contents/match_preview.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" @@ -484,6 +486,8 @@ BrowserView::BrowserView(Browser* browser) tabstrip_(NULL), toolbar_(NULL), infobar_container_(NULL), + sidebar_container_(NULL), + sidebar_split_(NULL), contents_container_(NULL), devtools_container_(NULL), preview_container_(NULL), @@ -497,6 +501,10 @@ BrowserView::BrowserView(Browser* browser) #endif { browser_->tabstrip_model()->AddObserver(this); + + registrar_.Add(this, + NotificationType::SIDEBAR_CHANGED, + Source<SidebarManager>(SidebarManager::GetInstance())); } BrowserView::~BrowserView() { @@ -618,6 +626,12 @@ gfx::Rect BrowserView::GetTabStripBounds() const { return frame_->GetBoundsForTabStrip(tabstrip_); } +int BrowserView::GetSidebarWidth() const { + if (!sidebar_container_ || !sidebar_container_->IsVisible()) + return 0; + return sidebar_split_->divider_offset(); +} + bool BrowserView::IsTabStripVisible() const { return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); } @@ -951,18 +965,24 @@ void BrowserView::RotatePaneFocus(bool forwards) { // focusable children it will be automatically skipped. std::vector<AccessibleToolbarView*> accessible_toolbars; GetAccessibleToolbars(&accessible_toolbars); - // Add NULL, which represents the tab contents getting focus - accessible_toolbars.push_back(NULL); - - // Figure out which toolbar (if any) currently has the focus. - AccessibleToolbarView* current_toolbar = NULL; + int toolbars_count = static_cast<int>(accessible_toolbars.size()); + + std::vector<views::View*> accessible_views( + accessible_toolbars.begin(), accessible_toolbars.end()); + accessible_views.push_back(GetTabContentsContainerView()); + if (sidebar_container_ && sidebar_container_->IsVisible()) + accessible_views.push_back(GetSidebarContainerView()); + if (devtools_container_->IsVisible()) + accessible_views.push_back(devtools_container_->GetFocusView()); + int count = static_cast<int>(accessible_views.size()); + + // Figure out which view (if any) currently has the focus. views::View* focused_view = GetRootView()->GetFocusedView(); int index = -1; - int count = static_cast<int>(accessible_toolbars.size()); if (focused_view) { - for (int i = 0; i < count; i++) { - if (accessible_toolbars[i]->IsParentOf(focused_view)) { - current_toolbar = accessible_toolbars[i]; + for (int i = 0; i < count; ++i) { + if (accessible_views[i] == focused_view || + accessible_views[i]->IsParentOf(focused_view)) { index = i; break; } @@ -971,7 +991,7 @@ void BrowserView::RotatePaneFocus(bool forwards) { // If the focus isn't currently in a toolbar, save the focus so we // can restore it if the user presses Escape. - if (focused_view && !current_toolbar) + if (focused_view && index >= toolbars_count) SaveFocusedView(); // Try to focus the next pane; if SetToolbarFocusAndFocusDefault returns @@ -981,16 +1001,15 @@ void BrowserView::RotatePaneFocus(bool forwards) { if (forwards) index = (index + 1) % count; else - index = ((index - 1) + count + count) % count; - AccessibleToolbarView* next_toolbar = accessible_toolbars[index]; + index = ((index - 1) + count) % count; - if (next_toolbar) { - if (next_toolbar->SetToolbarFocusAndFocusDefault( + if (index < toolbars_count) { + if (accessible_toolbars[index]->SetToolbarFocusAndFocusDefault( last_focused_view_storage_id_)) { break; } } else { - GetTabContentsContainerView()->RequestFocus(); + accessible_views[index]->RequestFocus(); break; } } @@ -1374,6 +1393,12 @@ views::View* BrowserView::GetTabContentsContainerView() const { return contents_container_->GetFocusView(); } +views::View* BrowserView::GetSidebarContainerView() const { + if (!sidebar_container_) + return NULL; + return sidebar_container_->GetFocusView(); +} + ToolbarView* BrowserView::GetToolbarView() const { return toolbar_; } @@ -1411,6 +1436,13 @@ void BrowserView::Observe(NotificationType type, break; } + case NotificationType::SIDEBAR_CHANGED: + if (Details<SidebarContainer>(details)->tab_contents() == + browser_->GetSelectedTabContents()) { + UpdateSidebar(); + } + break; + default: NOTREACHED() << "Got a notification we didn't register for!"; break; @@ -1430,6 +1462,7 @@ void BrowserView::TabDetachedAt(TabContents* contents, int index) { // on the selected TabContents when it is removed. contents_container_->ChangeTabContents(NULL); infobar_container_->ChangeTabContents(NULL); + UpdateSidebarForContents(NULL); UpdateDevToolsForContents(NULL); } } @@ -1843,18 +1876,42 @@ void BrowserView::Init() { contents_container_ = new TabContentsContainer; contents_ = new ContentsContainer(this, contents_container_); + + SkColor bg_color = GetWidget()->GetThemeProvider()-> + GetColor(BrowserThemeProvider::COLOR_TOOLBAR); + + bool sidebar_allowed = SidebarManager::IsSidebarAllowed(); + if (sidebar_allowed) { + sidebar_container_ = new TabContentsContainer; + sidebar_container_->SetID(VIEW_ID_SIDE_BAR_CONTAINER); + sidebar_container_->SetVisible(false); + + sidebar_split_ = new views::SingleSplitView( + contents_, + sidebar_container_, + views::SingleSplitView::HORIZONTAL_SPLIT); + sidebar_split_->SetID(VIEW_ID_SIDE_BAR_SPLIT); + sidebar_split_-> + SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_SIDE_BAR)); + sidebar_split_->set_background( + views::Background::CreateSolidBackground(bg_color)); + } + devtools_container_ = new TabContentsContainer; devtools_container_->SetID(VIEW_ID_DEV_TOOLS_DOCKED); devtools_container_->SetVisible(false); + + views::View* contents_view = contents_; + if (sidebar_allowed) + contents_view = sidebar_split_; + contents_split_ = new views::SingleSplitView( - contents_, + contents_view, devtools_container_, views::SingleSplitView::VERTICAL_SPLIT); contents_split_->SetID(VIEW_ID_CONTENTS_SPLIT); contents_split_-> SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_WEB_CONTENTS)); - SkColor bg_color = GetWidget()->GetThemeProvider()-> - GetColor(BrowserThemeProvider::COLOR_TOOLBAR); contents_split_->set_background( views::Background::CreateSolidBackground(bg_color)); AddChildView(contents_split_); @@ -1953,6 +2010,67 @@ bool BrowserView::MaybeShowInfoBar(TabContents* contents) { return true; } +void BrowserView::UpdateSidebar() { + UpdateSidebarForContents(GetSelectedTabContents()); + Layout(); +} + +void BrowserView::UpdateSidebarForContents(TabContents* tab_contents) { + if (!sidebar_container_) + return; // Happens when sidebar is not allowed. + if (!SidebarManager::GetInstance()) + return; // Happens only in tests. + + TabContents* sidebar_contents = NULL; + if (tab_contents) { + SidebarContainer* client_host = SidebarManager::GetInstance()-> + GetActiveSidebarContainerFor(tab_contents); + if (client_host) + sidebar_contents = client_host->sidebar_contents(); + } + + bool visible = NULL != sidebar_contents && + browser_->SupportsWindowFeature(Browser::FEATURE_SIDEBAR); + + bool should_show = visible && !sidebar_container_->IsVisible(); + bool should_hide = !visible && sidebar_container_->IsVisible(); + + // Update sidebar content. + TabContents* old_contents = sidebar_container_->tab_contents(); + sidebar_container_->ChangeTabContents(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) { + // Initial load, set to default value. + sidebar_width = sidebar_split_->width() / 7; + } + // Make sure user can see both panes. + int min_sidebar_width = sidebar_split_->GetMinimumSize().width(); + sidebar_width = std::min(sidebar_split_->width() - 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_split_->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(); + } +} + void BrowserView::UpdateDevToolsForContents(TabContents* tab_contents) { TabContents* devtools_contents = DevToolsWindow::GetDevToolsContents(tab_contents); @@ -2343,6 +2461,7 @@ void BrowserView::ProcessTabSelected(TabContents* new_contents, UpdateUIForContents(new_contents); if (change_tab_contents) contents_container_->ChangeTabContents(new_contents); + UpdateSidebarForContents(new_contents); UpdateDevToolsForContents(new_contents); // TODO(beng): This should be called automatically by ChangeTabContents, but I |