diff options
Diffstat (limited to 'chrome/browser')
38 files changed, 456 insertions, 34 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 1182059..901416d 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -511,6 +511,13 @@ void AutocompleteEditViewWin::SaveStateToTab(TabContents* tab) { void AutocompleteEditViewWin::Update( const TabContents* tab_for_state_restoring) { + // If we're switching to a tab with a collapsed toolbar, bail + // now, since we won't be showing the Omnibox anyway, and + // executing the code below just results in a flicker before + // the toolbar hides. + if (tab_for_state_restoring && tab_for_state_restoring->is_app()) + return; + const bool visibly_changed_permanent_text = model_->UpdatePermanentText(toolbar_model_->GetText()); diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 21ace5e..51c7764 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -1151,6 +1151,9 @@ bool Browser::SupportsWindowFeatureImpl(WindowFeature feature, if (type() == TYPE_NORMAL || type() == TYPE_EXTENSION_APP) features |= FEATURE_TABSTRIP; + // TODO(aa): This is kinda a hack. The toolbar is not really there, it is + // collapsed. We probably want to add a FEATURE_MINI_TOOLBAR to represent + // the collapsed state. if (type() == TYPE_NORMAL || type() == TYPE_EXTENSION_APP) features |= FEATURE_TOOLBAR; @@ -2364,6 +2367,10 @@ void Browser::ToggleUseVerticalTabs() { UseVerticalTabsChanged(); } +void Browser::SetToolbarVisibility(bool visible) { + window()->SetToolbarCollapsedMode(!visible); +} + /////////////////////////////////////////////////////////////////////////////// // Browser, TabStripModelObserver implementation: @@ -2447,6 +2454,8 @@ void Browser::TabSelectedAt(TabContents* old_contents, session_id(), tabstrip_model_.selected_index()); } } + + window()->SetToolbarCollapsedMode(!tabstrip_model_.IsToolbarVisible(index)); } void Browser::TabMoved(TabContents* contents, diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index eb8634a..5d7f6cc 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -651,6 +651,7 @@ class Browser : public TabStripModelDelegate, virtual void ToggleUseVerticalTabs(); virtual bool CanRestoreTab(); virtual void RestoreTab(); + virtual void SetToolbarVisibility(bool visible); // Overridden from TabStripModelObserver: virtual void TabInsertedAt(TabContents* contents, diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h index d4e679e..ad74673 100644 --- a/chrome/browser/browser_window.h +++ b/chrome/browser/browser_window.h @@ -309,6 +309,9 @@ class BrowserWindow { // Switches between available tabstrip display modes. virtual void ToggleTabStripMode() = 0; + // Set whether the toolbar displays in collapsed mode. + virtual void SetToolbarCollapsedMode(bool val) = 0; + // Construct a BrowserWindow implementation for the specified |browser|. static BrowserWindow* CreateBrowserWindow(Browser* browser); diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index e363a6e..6afc90f 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.h +++ b/chrome/browser/cocoa/browser_window_cocoa.h @@ -105,6 +105,7 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void Copy(); virtual void Paste(); virtual void ToggleTabStripMode(); + virtual void SetToolbarCollapsedMode(bool val) {}; // Overridden from NotificationObserver virtual void Observe(NotificationType type, diff --git a/chrome/browser/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/cocoa/location_bar/location_bar_view_mac.h index f5e895c..e07b112 100644 --- a/chrome/browser/cocoa/location_bar/location_bar_view_mac.h +++ b/chrome/browser/cocoa/location_bar/location_bar_view_mac.h @@ -72,6 +72,8 @@ class LocationBarViewMac : public AutocompleteEditController, virtual AutocompleteEditView* location_entry() { return edit_view_.get(); } + virtual void PushForceHidden() {} + virtual void PopForceHidden() {} virtual LocationBarTesting* GetLocationBarForTesting() { return this; } // Overridden from LocationBarTesting: diff --git a/chrome/browser/cocoa/tab_controller.mm b/chrome/browser/cocoa/tab_controller.mm index 040f9d6..50eb268 100644 --- a/chrome/browser/cocoa/tab_controller.mm +++ b/chrome/browser/cocoa/tab_controller.mm @@ -130,7 +130,10 @@ class MenuDelegate : public menus::SimpleMenuModel::Delegate { contextMenuDelegate_.reset( new TabControllerInternal::MenuDelegate(target_, self)); contextMenuModel_.reset(new TabMenuModel(contextMenuDelegate_.get(), - [self pinned])); + [self pinned], + false, // allow_toolbar_toggle + true)); // is_toolbar_visible + contextMenuController_.reset( [[MenuController alloc] initWithModel:contextMenuModel_.get() useWithPopUpButtonCell:NO]); diff --git a/chrome/browser/cocoa/tab_strip_controller_unittest.mm b/chrome/browser/cocoa/tab_strip_controller_unittest.mm index 2a161ab..61b0837 100644 --- a/chrome/browser/cocoa/tab_strip_controller_unittest.mm +++ b/chrome/browser/cocoa/tab_strip_controller_unittest.mm @@ -67,6 +67,8 @@ class TestTabStripDelegate : public TabStripModelDelegate { virtual bool UseVerticalTabs() const { return false; } virtual void ToggleUseVerticalTabs() {} + + virtual void SetToolbarVisibility(bool value) {} }; class TabStripControllerTest : public CocoaTest { diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc index ed44ec4..93f29c4 100644 --- a/chrome/browser/extensions/extension_prefs.cc +++ b/chrome/browser/extensions/extension_prefs.cc @@ -35,6 +35,9 @@ const wchar_t kPrefVersion[] = L"manifest.version"; // Indicates if an extension is blacklisted: const wchar_t kPrefBlacklist[] = L"blacklist"; +// Indicates whether the toolbar should be shown on app tabs. +const wchar_t kPrefAppTabToolbars[] = L"app_tab_toolbars"; + // Indicates whether to show an install warning when the user enables. const wchar_t kExtensionDidEscalatePermissions[] = L"install_warning_on_enable"; @@ -777,6 +780,32 @@ std::set<std::string> ExtensionPrefs::GetIdleInstallInfoIds() { return result; } +bool ExtensionPrefs::AreAppTabToolbarsVisible( + const std::string& extension_id) { + // Default to hiding toolbars. + bool show_toolbars = false; + DictionaryValue* pref = GetExtensionPref(extension_id); + if (!pref) + return show_toolbars; + + pref->GetBoolean( + ASCIIToWide(extension_id) + L"." + kPrefAppTabToolbars, &show_toolbars); + return show_toolbars; +} + +void ExtensionPrefs::SetAppTabToolbarVisibility( + const std::string& extension_id, bool value) { + DictionaryValue* pref = GetOrCreateExtensionPref(extension_id); + std::wstring key = ASCIIToWide(extension_id) + L"." + kPrefAppTabToolbars; + + if (value) + pref->SetBoolean(key, true); + else + pref->Remove(key, NULL); // False is the default value. + + prefs_->ScheduleSavePersistentPrefs(); +} + // static void ExtensionPrefs::RegisterUserPrefs(PrefService* prefs) { diff --git a/chrome/browser/extensions/extension_prefs.h b/chrome/browser/extensions/extension_prefs.h index 38b8402..6977fb4 100644 --- a/chrome/browser/extensions/extension_prefs.h +++ b/chrome/browser/extensions/extension_prefs.h @@ -142,6 +142,12 @@ class ExtensionPrefs { // Returns the extension id's that have idle install information. std::set<std::string> GetIdleInstallInfoIds(); + // Returns whether app toolbars are visible for the specified extension. + bool AreAppTabToolbarsVisible(const std::string& extension_id); + + // Set whether app toolbars are visible for the specified extension. + void SetAppTabToolbarVisibility(const std::string& extension_id, bool value); + static void RegisterUserPrefs(PrefService* prefs); // The underlying PrefService. diff --git a/chrome/browser/extensions/extension_prefs_unittest.cc b/chrome/browser/extensions/extension_prefs_unittest.cc index 812891b..26df5b1 100644 --- a/chrome/browser/extensions/extension_prefs_unittest.cc +++ b/chrome/browser/extensions/extension_prefs_unittest.cc @@ -311,6 +311,41 @@ class ExtensionPrefsIdleInstallInfo : public ExtensionPrefsTest { }; TEST_F(ExtensionPrefsIdleInstallInfo, IdleInstallInfo) {} +class ExtensionPrefsAppToolbars : public ExtensionPrefsTest { + public: + virtual void Initialize() { + // We test three different configurations -- the default value, and being + // overrridden set to on or off. + extension_id_default_ = + prefs_.AddExtensionAndReturnId("app_toolbars_default"); + + extension_id_overridden_on_ = + prefs_.AddExtensionAndReturnId("app_toolbars_overridden_on"); + prefs()->SetAppTabToolbarVisibility(extension_id_overridden_on_, true); + + extension_id_overridden_off_ = + prefs_.AddExtensionAndReturnId("app_toolbars_overridden_off"); + prefs()->SetAppTabToolbarVisibility(extension_id_overridden_off_, false); + } + + virtual void Verify() { + // Toolbars default to hidden. + EXPECT_FALSE(prefs()->AreAppTabToolbarsVisible(extension_id_default_)); + + EXPECT_TRUE(prefs()->AreAppTabToolbarsVisible( + extension_id_overridden_on_)); + EXPECT_FALSE(prefs()->AreAppTabToolbarsVisible( + extension_id_overridden_off_)); + } + + private: + // The ids of our three test extensions. + std::string extension_id_default_; + std::string extension_id_overridden_on_; + std::string extension_id_overridden_off_; +}; +TEST_F(ExtensionPrefsAppToolbars, ExtensionPrefsAppToolbars) {} + class ExtensionPrefsOnExtensionInstalled : public ExtensionPrefsTest { public: virtual void Initialize() { diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 03b1af0..77b082c 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -123,6 +123,7 @@ class BrowserWindowGtk : public BrowserWindow, virtual void Copy(); virtual void Paste(); virtual void ToggleTabStripMode() {} + virtual void SetToolbarCollapsedMode(bool val) {} // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h index 7600390..870e415 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.h +++ b/chrome/browser/gtk/location_bar_view_gtk.h @@ -114,6 +114,8 @@ class LocationBarViewGtk : public AutocompleteEditController, virtual AutocompleteEditView* location_entry() { return location_entry_.get(); } + virtual void PushForceHidden() {} + virtual void PopForceHidden() {} virtual LocationBarTesting* GetLocationBarForTesting() { return this; } // Implement the LocationBarTesting interface. diff --git a/chrome/browser/gtk/tabs/tab_gtk.cc b/chrome/browser/gtk/tabs/tab_gtk.cc index b62191d..7383a5e 100644 --- a/chrome/browser/gtk/tabs/tab_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_gtk.cc @@ -38,7 +38,7 @@ class TabGtk::ContextMenuController : public menus::SimpleMenuModel::Delegate { public: explicit ContextMenuController(TabGtk* tab) : tab_(tab), - model_(this, tab->delegate()->IsTabPinned(tab)) { + model_(this, tab->delegate()->IsTabPinned(tab), false, true) { menu_.reset(new MenuGtk(NULL, &model_)); } diff --git a/chrome/browser/location_bar.h b/chrome/browser/location_bar.h index bb6484e..8b18be6 100644 --- a/chrome/browser/location_bar.h +++ b/chrome/browser/location_bar.h @@ -69,6 +69,13 @@ class LocationBar { virtual const AutocompleteEditView* location_entry() const = 0; virtual AutocompleteEditView* location_entry() = 0; + // Hides the edit field of the location bar if it hasn't already been + // force-hidden. The force hidden count is tracked, so calling multiple + // times is allowed, you just have to be sure to call PopForceHidden + // the same number of times. Currently, this is only needed for Windows. + virtual void PushForceHidden() = 0; + virtual void PopForceHidden() = 0; + // Returns a pointer to the testing interface. virtual LocationBarTesting* GetLocationBarForTesting() = 0; diff --git a/chrome/browser/tab_menu_model.cc b/chrome/browser/tab_menu_model.cc index 6b8dc17..41667b2 100644 --- a/chrome/browser/tab_menu_model.cc +++ b/chrome/browser/tab_menu_model.cc @@ -10,9 +10,11 @@ #include "grit/generated_resources.h" TabMenuModel::TabMenuModel(menus::SimpleMenuModel::Delegate* delegate, - bool is_pinned) + bool is_pinned, + bool allow_toolbar_toggle, + bool is_toolbar_visible) : menus::SimpleMenuModel(delegate) { - Build(is_pinned); + Build(is_pinned, allow_toolbar_toggle, is_toolbar_visible); } // static @@ -27,7 +29,8 @@ bool TabMenuModel::AreVerticalTabsEnabled() { #endif } -void TabMenuModel::Build(bool is_pinned) { +void TabMenuModel::Build(bool is_pinned, bool allow_toolbar_toggle, + bool is_toolbar_visible) { AddItemWithStringId(TabStripModel::CommandNewTab, IDS_TAB_CXMENU_NEWTAB); AddSeparator(); AddItemWithStringId(TabStripModel::CommandReload, IDS_TAB_CXMENU_RELOAD); @@ -36,6 +39,12 @@ void TabMenuModel::Build(bool is_pinned) { AddItemWithStringId( TabStripModel::CommandTogglePinned, is_pinned ? IDS_TAB_CXMENU_UNPIN_TAB : IDS_TAB_CXMENU_PIN_TAB); + if (allow_toolbar_toggle) { + AddItemWithStringId( + TabStripModel::CommandToggleToolbar, + is_toolbar_visible ? IDS_TAB_CXMENU_HIDE_TOOLBAR : + IDS_TAB_CXMENU_SHOW_TOOLBAR); + } AddSeparator(); AddItemWithStringId(TabStripModel::CommandCloseTab, IDS_TAB_CXMENU_CLOSETAB); diff --git a/chrome/browser/tab_menu_model.h b/chrome/browser/tab_menu_model.h index a910983..d0c29eb 100644 --- a/chrome/browser/tab_menu_model.h +++ b/chrome/browser/tab_menu_model.h @@ -15,14 +15,16 @@ class Browser; // of the tab a new TabMenuModel should be created each time the menu is shown. class TabMenuModel : public menus::SimpleMenuModel { public: - TabMenuModel(menus::SimpleMenuModel::Delegate* delegate, bool is_pinned); + TabMenuModel(menus::SimpleMenuModel::Delegate* delegate, bool is_pinned, + bool allow_toolbar_toggle, bool is_toolbar_visible); virtual ~TabMenuModel() {} // Returns true if vertical tabs are enabled. static bool AreVerticalTabsEnabled(); private: - void Build(bool is_pinned); + void Build(bool is_pinned, bool allow_toolbar_toggle, + bool is_toolbar_visible); DISALLOW_COPY_AND_ASSIGN(TabMenuModel); }; diff --git a/chrome/browser/tab_menu_model_unittest.cc b/chrome/browser/tab_menu_model_unittest.cc index eaaa72e..4c07b96 100644 --- a/chrome/browser/tab_menu_model_unittest.cc +++ b/chrome/browser/tab_menu_model_unittest.cc @@ -13,7 +13,7 @@ class TabMenuModelTest : public PlatformTest, public MenuModelTest { }; TEST_F(TabMenuModelTest, Basics) { - TabMenuModel model(&delegate_, true); + TabMenuModel model(&delegate_, true, false, true); // Verify it has items. The number varies by platform, so we don't check // the exact number. diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc index 22cea3b..9fe21e6 100644 --- a/chrome/browser/tabs/tab_strip_model.cc +++ b/chrome/browser/tabs/tab_strip_model.cc @@ -121,6 +121,9 @@ TabStripModel::TabStripModel(TabStripModelDelegate* delegate, Profile* profile) registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, Source<Profile>(profile_)); + registrar_.Add(this, + NotificationType::EXTENSION_APP_TOOLBAR_VISIBILITY_CHANGED, + NotificationService::AllSources()); order_controller_ = new TabStripModelOrderController(this); } @@ -525,6 +528,16 @@ bool TabStripModel::IsAppTab(int index) const { return contents && contents->is_app(); } +bool TabStripModel::IsToolbarVisible(int index) const { + Extension* extension_app = GetTabContentsAt(index)->extension_app(); + if (!extension_app) + return true; + + ExtensionsService* service = profile()->GetExtensionsService(); + ExtensionPrefs* prefs = service->extension_prefs(); + return prefs->AreAppTabToolbarsVisible(extension_app->id()); +} + bool TabStripModel::IsPhantomTab(int index) const { return IsTabPinned(index) && GetTabContentsAt(index)->controller().needs_reload(); @@ -695,6 +708,8 @@ bool TabStripModel::IsContextMenuCommandEnabled( return delegate_->CanRestoreTab(); case CommandTogglePinned: return true; + case CommandToggleToolbar: + return true; case CommandBookmarkAllTabs: return delegate_->CanBookmarkAllTabs(); case CommandUseVerticalTabs: @@ -780,6 +795,32 @@ void TabStripModel::ExecuteContextMenuCommand( } break; } + case CommandToggleToolbar: { + UserMetrics::RecordAction( + UserMetricsAction("TabContextMenu_ToggleToolbar"), + profile_); + + SelectTabContentsAt(context_index, true); + + Extension* extension_app = + GetTabContentsAt(context_index)->extension_app(); + if (!extension_app) + break; + + ExtensionsService* service = profile()->GetExtensionsService(); + ExtensionPrefs* prefs = service->extension_prefs(); + bool new_val = !prefs->AreAppTabToolbarsVisible(extension_app->id()); + prefs->SetAppTabToolbarVisibility(extension_app->id(), new_val); + + // There might be multiple browsers displaying this app, so we send a + // notification to update them all. + NotificationService::current()->Notify( + NotificationType::EXTENSION_APP_TOOLBAR_VISIBILITY_CHANGED, + Source<Extension>(extension_app), + Details<bool>(&new_val)); + + break; + } case CommandBookmarkAllTabs: { UserMetrics::RecordAction( @@ -866,6 +907,17 @@ void TabStripModel::Observe(NotificationType type, break; } + case NotificationType::EXTENSION_APP_TOOLBAR_VISIBILITY_CHANGED: { + Extension* extension = Source<Extension>(source).ptr(); + bool* value = Details<bool>(details).ptr(); + TabContents* selected = GetSelectedTabContents(); + + if (selected && selected->extension_app() == extension) + delegate_->SetToolbarVisibility(*value); + + break; + } + default: NOTREACHED(); } diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h index 5e43d85..c00dbff 100644 --- a/chrome/browser/tabs/tab_strip_model.h +++ b/chrome/browser/tabs/tab_strip_model.h @@ -236,6 +236,9 @@ class TabStripModelDelegate { // Toggles the use of the vertical tabstrip. virtual void ToggleUseVerticalTabs() = 0; + + // Set the visiblity of the toolbar. + virtual void SetToolbarVisibility(bool value) = 0; }; //////////////////////////////////////////////////////////////////////////////// @@ -548,6 +551,9 @@ class TabStripModel : public NotificationObserver { // See description above class for details on app tabs. bool IsAppTab(int index) const; + // Returns true if the toolbar is visible for the tab at |index|. + bool IsToolbarVisible(int index) const; + // Returns true if the tab is a phantom tab. A phantom tab is one where the // renderer has not been loaded. // See description above class for details on phantom tabs. @@ -620,6 +626,7 @@ class TabStripModel : public NotificationObserver { CommandCloseTabsToRight, CommandRestoreTab, CommandTogglePinned, + CommandToggleToolbar, CommandBookmarkAllTabs, CommandUseVerticalTabs, CommandLast diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc index 90f3012..422a173 100644 --- a/chrome/browser/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/tabs/tab_strip_model_unittest.cc @@ -80,6 +80,7 @@ class TabStripDummyDelegate : public TabStripModelDelegate { virtual void BookmarkAllTabs() {} virtual bool UseVerticalTabs() const { return false; } virtual void ToggleUseVerticalTabs() {} + virtual void SetToolbarVisibility(bool val) {} private: // A dummy TabContents we give to callers that expect us to actually build a diff --git a/chrome/browser/view_ids.h b/chrome/browser/view_ids.h index 8211ea2..e472526 100644 --- a/chrome/browser/view_ids.h +++ b/chrome/browser/view_ids.h @@ -30,6 +30,8 @@ enum ViewID { // ID for any tab. Currently only used on views. VIEW_ID_TAB, + VIEW_ID_EXTENSION_APP_ICON, + VIEW_ID_EXTENSION_APP_TITLE, VIEW_ID_TAB_STRIP, // Toolbar & toolbar elements. diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 26baaac..83bbfef 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -460,7 +460,11 @@ void BookmarkBarView::SetPageNavigator(PageNavigator* navigator) { } gfx::Size BookmarkBarView::GetPreferredSize() { - return LayoutItems(true); + // Extension apps don't show the bookmark bar. + if (!OnAppsPage()) + return LayoutItems(true); + else + return gfx::Size(); } gfx::Size BookmarkBarView::GetMinimumSize() { @@ -752,6 +756,11 @@ bool BookmarkBarView::OnNewTabPage() const { browser_->GetSelectedTabContents()->ShouldShowBookmarkBar()); } +bool BookmarkBarView::OnAppsPage() const { + return (browser_ && browser_->GetSelectedTabContents() && + browser_->GetSelectedTabContents()->is_app()); +} + int BookmarkBarView::GetToolbarOverlap(bool return_max) { return static_cast<int>(kToolbarOverlap * (return_max ? 1.0 : size_animation_->GetCurrentValue())); diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h index b73cbe0..e708b99 100644 --- a/chrome/browser/views/bookmark_bar_view.h +++ b/chrome/browser/views/bookmark_bar_view.h @@ -162,6 +162,9 @@ class BookmarkBarView : public DetachableToolbarView, // True if we're on a page where the bookmarks bar is always visible. bool OnNewTabPage() const; + // True if we're on an extension apps page. + bool OnAppsPage() const; + // How much we want the bookmark bar to overlap the toolbar. If |return_max| // is true, we return the maximum overlap rather than the current overlap. int GetToolbarOverlap(bool return_max); diff --git a/chrome/browser/views/browser_actions_container.cc b/chrome/browser/views/browser_actions_container.cc index d5a8fde..65f2d31 100644 --- a/chrome/browser/views/browser_actions_container.cc +++ b/chrome/browser/views/browser_actions_container.cc @@ -24,6 +24,7 @@ #include "chrome/browser/views/detachable_toolbar_view.h" #include "chrome/browser/views/extensions/browser_action_drag_data.h" #include "chrome/browser/views/extensions/extension_popup.h" +#include "chrome/browser/views/toolbar_view.h" #include "chrome/common/extensions/extension_action.h" #include "chrome/common/extensions/extension_resource.h" #include "chrome/common/notification_source.h" @@ -611,7 +612,11 @@ gfx::Size BrowserActionsContainer::GetPreferredSize() { } void BrowserActionsContainer::Layout() { - if (browser_action_views_.size() == 0) { + // The parent can be visible, but collapsed. In this case we don't + // want the browser action container to be visible. + ToolbarView* parent = reinterpret_cast<ToolbarView*>(GetParent()); + + if (browser_action_views_.size() == 0 || parent->collapsed()) { SetVisible(false); resize_gripper_->SetVisible(false); chevron_->SetVisible(false); diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 7359923..ea14236 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -100,6 +100,10 @@ static int explicit_show_state = -1; // How round the 'new tab' style bookmarks bar is. static const int kNewtabBarRoundness = 5; + +// The maximum width of the big title shown for extension app windows. +static const int kExtensionAppTitleMaxWidth = 150; + // ------------ // Returned from BrowserView::GetClassName. @@ -407,6 +411,8 @@ BrowserView::BrowserView(Browser* browser) frame_(NULL), browser_(browser), active_bookmark_bar_(NULL), + extension_app_icon_(NULL), + extension_app_title_(NULL), tabstrip_(NULL), toolbar_(NULL), infobar_container_(NULL), @@ -419,7 +425,8 @@ BrowserView::BrowserView(Browser* browser) hung_window_detector_(&hung_plugin_action_), ticker_(0), #endif - extension_shelf_(NULL) { + extension_shelf_(NULL), + extension_app_icon_loader_(this) { browser_->tabstrip_model()->AddObserver(this); } @@ -1285,6 +1292,11 @@ void BrowserView::ToggleTabStripMode() { frame_->TabStripDisplayModeChanged(); } +void BrowserView::SetToolbarCollapsedMode(bool val) { + toolbar_->SetCollapsed(val); + Layout(); +} + /////////////////////////////////////////////////////////////////////////////// // BrowserView, BrowserWindowTesting implementation: @@ -1706,6 +1718,8 @@ void BrowserView::InitTabStrip(TabStripModel* model) { tabstrip_ = new TabStrip(tabstrip_controller); tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP)); + if (browser_->extension_app() && tabstrip_->AsTabStrip()) + tabstrip_->AsTabStrip()->set_new_tab_button_enabled(false); AddChildView(tabstrip_); tabstrip_controller->InitFromModel(tabstrip_); @@ -1738,12 +1752,46 @@ void BrowserView::Init() { LoadAccelerators(); SetAccessibleName(l10n_util::GetString(IDS_PRODUCT_NAME)); + if (browser_->extension_app()) { + extension_app_icon_ = new views::ImageView(); + extension_app_icon_->SetID(VIEW_ID_EXTENSION_APP_ICON); + AddChildView(extension_app_icon_); + + extension_app_title_ = new views::Label(); + extension_app_title_->SetFont( + extension_app_title_->font().DeriveFont(1, gfx::Font::BOLD)); + extension_app_title_->SetColor(SK_ColorWHITE); + extension_app_title_->SetID(VIEW_ID_EXTENSION_APP_TITLE); + AddChildView(extension_app_title_); + + extension_app_icon_loader_.LoadImage( + browser_->extension_app(), + browser_->extension_app()->GetIconPath( + Extension::EXTENSION_ICON_MEDIUM), + gfx::Size(Extension::EXTENSION_ICON_SMALL, + Extension::EXTENSION_ICON_SMALL), + ImageLoadingTracker::CACHE); + + extension_app_title_->SetText( + UTF8ToWide(browser_->extension_app()->name())); + extension_app_title_->SizeToPreferredSize(); + + if (extension_app_title_->width() > kExtensionAppTitleMaxWidth) { + extension_app_title_->SetBounds(extension_app_title_->x(), + extension_app_title_->y(), + kExtensionAppTitleMaxWidth, + extension_app_title_->height()); + } + } + InitTabStrip(browser_->tabstrip_model()); toolbar_ = new ToolbarView(browser_.get()); AddChildView(toolbar_); toolbar_->Init(browser_->profile()); toolbar_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TOOLBAR)); + if (browser_->type() == Browser::TYPE_EXTENSION_APP) + toolbar_->SetCollapsed(true); infobar_container_ = new InfoBarContainer(this); AddChildView(infobar_container_); @@ -1816,6 +1864,12 @@ void BrowserView::InitSystemMenu() { } #endif +void BrowserView::OnImageLoaded(SkBitmap* image, ExtensionResource resource, + int index) { + if (image) + extension_app_icon_->SetImage(*image); +} + BrowserViewLayout* BrowserView::GetBrowserViewLayout() const { return static_cast<BrowserViewLayout*>(GetLayoutManager()); } @@ -1969,10 +2023,6 @@ void BrowserView::ProcessFullscreen(bool fullscreen) { // thus are slow and look ugly ignore_layout_ = true; LocationBarView* location_bar = toolbar_->location_bar(); -#if defined(OS_WIN) - AutocompleteEditViewWin* edit_view = - static_cast<AutocompleteEditViewWin*>(location_bar->location_entry()); -#endif if (!fullscreen) { // Hide the fullscreen bubble as soon as possible, since the mode toggle can // take enough time for the user to notice. @@ -1984,15 +2034,12 @@ void BrowserView::ProcessFullscreen(bool fullscreen) { if (focus_manager->GetFocusedView() == location_bar) focus_manager->ClearFocus(); -#if defined(OS_WIN) // If we don't hide the edit and force it to not show until we come out of // fullscreen, then if the user was on the New Tab Page, the edit contents // will appear atop the web contents once we go into fullscreen mode. This // has something to do with how we move the main window while it's hidden; // if we don't hide the main window below, we don't get this problem. - edit_view->set_force_hidden(true); - ShowWindow(edit_view->m_hWnd, SW_HIDE); -#endif + location_bar->PushForceHidden(); } #if defined(OS_WIN) frame_->GetWindow()->PushForceHidden(); @@ -2029,11 +2076,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen) { browser_.get())); } } else { -#if defined(OS_WIN) // Show the edit again since we're no longer in fullscreen mode. - edit_view->set_force_hidden(false); - ShowWindow(edit_view->m_hWnd, SW_SHOW); -#endif + location_bar->PopForceHidden(); } // Undo our anti-jankiness hacks and force the window to relayout now that diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 8c00550..4914c00 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -16,6 +16,7 @@ #include "build/build_config.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" +#include "chrome/browser/extensions/image_loading_tracker.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/views/frame/browser_bubble_host.h" #include "chrome/browser/views/frame/browser_frame.h" @@ -24,6 +25,8 @@ #include "chrome/browser/views/tabs/base_tab_strip.h" #include "chrome/browser/views/unhandled_keyboard_event_handler.h" #include "gfx/native_widget_types.h" +#include "views/controls/image_view.h" +#include "views/controls/label.h" #include "views/window/client_view.h" #include "views/window/window_delegate.h" @@ -80,7 +83,8 @@ class BrowserView : public BrowserBubbleHost, public menus::SimpleMenuModel::Delegate, public views::WindowDelegate, public views::ClientView, - public InfoBarContainer::Delegate { + public InfoBarContainer::Delegate, + public ImageLoadingTracker::Observer { public: // The browser view's class name. static const char kViewClassName[]; @@ -144,6 +148,14 @@ class BrowserView : public BrowserBubbleHost, // offset of IDR_THEME_TOOLBAR. gfx::Rect GetTabStripBounds() const; + // Accessor for the big icon used with TYPE_EXTENSION_APP, or NULL if this + // browser isn't TYPE_EXTENSION_APP. + views::ImageView* extension_app_icon() const { return extension_app_icon_; } + + // Accessor for the big title used with TYPE_EXTENSION_APP, or NULL if this + // browser isn't TYPE_EXTENSION_APP. + views::Label* extension_app_title() const { return extension_app_title_; } + // Accessor for the TabStrip. BaseTabStrip* tabstrip() const { return tabstrip_; } @@ -237,6 +249,10 @@ class BrowserView : public BrowserBubbleHost, // Called when the activation of the frame changes. virtual void ActivationChanged(bool activated); + // Overriden from ImageLoadingTracker::Observer. + virtual void OnImageLoaded(SkBitmap* image, ExtensionResource resource, + int index); + // Overridden from BrowserWindow: virtual void Show(); virtual void SetBounds(const gfx::Rect& bounds); @@ -315,6 +331,7 @@ class BrowserView : public BrowserBubbleHost, virtual void Copy(); virtual void Paste(); virtual void ToggleTabStripMode(); + virtual void SetToolbarCollapsedMode(bool val); // Overridden from BrowserWindowTesting: virtual BookmarkBarView* GetBookmarkBarView() const; @@ -493,6 +510,14 @@ class BrowserView : public BrowserBubbleHost, // or is bookmark_bar_view_ if the bookmark bar is showing. views::View* active_bookmark_bar_; + // The big icon in the top-left if this browser is TYPE_EXTENSION_APP, or + // NULL otherwise. + views::ImageView* extension_app_icon_; + + // The big title text in the top-left if this browser is TYPE_EXTENSION_APP, + // or NULL otherwise. + views::Label* extension_app_title_; + // The TabStrip. BaseTabStrip* tabstrip_; @@ -575,6 +600,9 @@ class BrowserView : public BrowserBubbleHost, scoped_ptr<AccessibleViewHelper> accessible_view_helper_; + // Loads extension_app_icon_ asynchronously on the file thread. + ImageLoadingTracker extension_app_icon_loader_; + DISALLOW_COPY_AND_ASSIGN(BrowserView); }; diff --git a/chrome/browser/views/frame/browser_view_layout.cc b/chrome/browser/views/frame/browser_view_layout.cc index e7d807b..a332beb 100644 --- a/chrome/browser/views/frame/browser_view_layout.cc +++ b/chrome/browser/views/frame/browser_view_layout.cc @@ -32,6 +32,8 @@ const int kToolbarTabStripVerticalOverlap = 3; // An offset distance between certain toolbars and the toolbar that preceded // them in layout. const int kSeparationLineHeight = 1; +// Spacing between extension app icon and title. +const int kExtensionAppIconTitleSpacing = 4; } // namespace @@ -39,7 +41,9 @@ const int kSeparationLineHeight = 1; // BrowserViewLayout, public: BrowserViewLayout::BrowserViewLayout() - : tabstrip_(NULL), + : extension_app_icon_(NULL), + extension_app_title_(NULL), + tabstrip_(NULL), toolbar_(NULL), contents_split_(NULL), contents_container_(NULL), @@ -202,6 +206,8 @@ void BrowserViewLayout::Installed(views::View* host) { extension_shelf_ = NULL; active_bookmark_bar_ = NULL; tabstrip_ = NULL; + extension_app_icon_ = NULL; + extension_app_title_ = NULL; browser_view_ = static_cast<BrowserView*>(host); } @@ -231,6 +237,12 @@ void BrowserViewLayout::ViewAdded(views::View* host, views::View* view) { case VIEW_ID_TAB_STRIP: tabstrip_ = static_cast<BaseTabStrip*>(view); break; + case VIEW_ID_EXTENSION_APP_ICON: + extension_app_icon_ = static_cast<views::ImageView*>(view); + break; + case VIEW_ID_EXTENSION_APP_TITLE: + extension_app_title_ = static_cast<views::Label*>(view); + break; } } @@ -244,6 +256,7 @@ void BrowserViewLayout::ViewRemoved(views::View* host, views::View* view) { void BrowserViewLayout::Layout(views::View* host) { vertical_layout_rect_ = browser_view_->GetLocalBounds(true); + LayoutExtensionAppIconAndTitle(); int top = LayoutTabStrip(); top = LayoutToolbar(top); top = LayoutBookmarkAndInfoBars(top); @@ -272,6 +285,26 @@ gfx::Size BrowserViewLayout::GetPreferredSize(views::View* host) { ////////////////////////////////////////////////////////////////////////////// // BrowserViewLayout, private: +void BrowserViewLayout::LayoutExtensionAppIconAndTitle() { + if (browser_view_->browser()->type() != Browser::TYPE_EXTENSION_APP) + return; + + extension_app_icon_->SetVisible(true); + extension_app_icon_->SetBounds(0, 0, Extension::EXTENSION_ICON_SMALL, + Extension::EXTENSION_ICON_SMALL); + + extension_app_title_->SetVisible(true); + + // Position the title vertically centered with the icon and slightly to its + // right. + extension_app_title_->SetX( + extension_app_icon_->x() + extension_app_icon_->width() + + kExtensionAppIconTitleSpacing); + extension_app_title_->SetY( + extension_app_icon_->y() + + ((extension_app_icon_->height() - extension_app_title_->height()) / 2)); +} + int BrowserViewLayout::LayoutTabStrip() { if (!browser_view_->IsTabStripVisible()) { tabstrip_->SetVisible(false); @@ -310,8 +343,15 @@ int BrowserViewLayout::LayoutToolbar(int top) { y -= ((visible && browser_view_->IsTabStripVisible()) ? kToolbarTabStripVerticalOverlap : 0); } - int height = visible ? toolbar_->GetPreferredSize().height() : 0; - toolbar_->SetVisible(visible); + + int height = 0; + if (visible) { + height = toolbar_->GetPreferredSize().height(); + toolbar_->SetVisible(true); + } else { + toolbar_->SetVisible(false); + } + toolbar_->SetBounds(vertical_layout_rect_.x(), y, browser_view_width, height); return y + height; } diff --git a/chrome/browser/views/frame/browser_view_layout.h b/chrome/browser/views/frame/browser_view_layout.h index 7291e1b..3c187bd 100644 --- a/chrome/browser/views/frame/browser_view_layout.h +++ b/chrome/browser/views/frame/browser_view_layout.h @@ -47,6 +47,9 @@ class BrowserViewLayout : public views::LayoutManager { // for laying out subsequent controls. virtual int LayoutTabStrip(); + // Layout the big icon and title in the top left of extension app windows. + void LayoutExtensionAppIconAndTitle(); + // Layout the following controls, starting at |top|, returns the coordinate // of the bottom of the control, for laying out the next control. virtual int LayoutToolbar(int top); @@ -76,6 +79,8 @@ class BrowserViewLayout : public views::LayoutManager { } // Child views that the layout manager manages. + views::ImageView* extension_app_icon_; + views::Label* extension_app_title_; BaseTabStrip* tabstrip_; ToolbarView* toolbar_; views::View* contents_split_; diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc index 16a51fe..fc6f4de 100644 --- a/chrome/browser/views/frame/opaque_browser_frame_view.cc +++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc @@ -95,6 +95,8 @@ const int kNewTabCaptionMaximizedSpacing = 16; // How far to indent the tabstrip from the left side of the screen when there // is no OTR icon. const int kTabStripIndent = 1; +// Spacing between extension app icon/title and tab strip. +const int kExtensionAppTabStripLeftSpacing = 10; // Padding between the caption and start of vertical tabs. const int kVerticalTabPadding = 6; // Inset from the top of the toolbar/tabstrip to the shadow. Used only for @@ -216,6 +218,16 @@ gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip( int tabstrip_width = minimize_button_->x() - tabstrip_x - (frame_->GetWindow()->IsMaximized() ? kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing); + + if (browser_view_->browser()->type() == Browser::TYPE_EXTENSION_APP) { + int tabstrip_offset = browser_view_->extension_app_title()->x() + + browser_view_->extension_app_title()->width() + + kExtensionAppTabStripLeftSpacing; + + tabstrip_x += tabstrip_offset; + tabstrip_width -= tabstrip_offset; + } + return gfx::Rect(tabstrip_x, tabstrip_y, std::max(0, tabstrip_width), tabstrip->GetPreferredHeight()); diff --git a/chrome/browser/views/location_bar/location_bar_view.cc b/chrome/browser/views/location_bar/location_bar_view.cc index 4072c58..4dffa4e 100644 --- a/chrome/browser/views/location_bar/location_bar_view.cc +++ b/chrome/browser/views/location_bar/location_bar_view.cc @@ -98,6 +98,7 @@ LocationBarView::LocationBarView(Profile* profile, keyword_hint_view_(NULL), star_view_(NULL), mode_(mode), + force_hidden_count_(0), show_focus_rect_(false), ALLOW_THIS_IN_INITIALIZER_LIST(first_run_bubble_(this)) { DCHECK(profile_); @@ -987,6 +988,28 @@ void LocationBarView::Revert() { location_entry_->RevertAll(); } +void LocationBarView::PushForceHidden() { +#if defined(OS_WIN) + if (force_hidden_count_++ == 0) { + location_entry_->set_force_hidden(true); + ShowWindow(location_entry_->m_hWnd, SW_HIDE); + } +#endif +} + +void LocationBarView::PopForceHidden() { +#if defined(OS_WIN) + if (force_hidden_count_ == 0) { + NOTREACHED() << "Unmatched PopForceHidden() call!"; + return; + } + if (--force_hidden_count_ == 0) { + location_entry_->set_force_hidden(false); + ShowWindow(location_entry_->m_hWnd, SW_SHOW); + } +#endif +} + int LocationBarView::PageActionVisibleCount() { int result = 0; for (size_t i = 0; i < page_action_views_.size(); i++) { diff --git a/chrome/browser/views/location_bar/location_bar_view.h b/chrome/browser/views/location_bar/location_bar_view.h index ca092bd..84270dd 100644 --- a/chrome/browser/views/location_bar/location_bar_view.h +++ b/chrome/browser/views/location_bar/location_bar_view.h @@ -211,6 +211,8 @@ class LocationBarView : public LocationBar, virtual AutocompleteEditView* location_entry() { return location_entry_.get(); } + virtual void PushForceHidden(); + virtual void PopForceHidden(); virtual LocationBarTesting* GetLocationBarForTesting() { return this; } // Overridden from LocationBarTesting: @@ -347,6 +349,10 @@ class LocationBarView : public LocationBar, // The mode that dictates how the bar shows. Mode mode_; + // Counts the number of times consumers have asked us to be hidden. + // We should actually be hidden iff this is greater than zero. + int force_hidden_count_; + // True if we should show a focus rect while the location entry field is // focused. Used when the toolbar is in full keyboard accessibility mode. bool show_focus_rect_; diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/views/tabs/browser_tab_strip_controller.cc index 1221133..474e48f 100644 --- a/chrome/browser/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/views/tabs/browser_tab_strip_controller.cc @@ -36,7 +36,8 @@ class BrowserTabStripController::TabContextMenuContents TabContextMenuContents(BaseTab* tab, BrowserTabStripController* controller) : ALLOW_THIS_IN_INITIALIZER_LIST( - model_(this, controller->IsTabPinned(tab))), + model_(this, controller->IsTabPinned(tab), controller->IsAppTab(tab), + controller->IsToolbarVisible(tab))), tab_(tab), controller_(controller), last_command_(TabStripModel::CommandFirst) { @@ -170,6 +171,22 @@ bool BrowserTabStripController::IsTabPinned(BaseTab* tab) { return IsTabPinned(tabstrip_->GetModelIndexOfBaseTab(tab)); } +bool BrowserTabStripController::IsAppTab(BaseTab* tab) { + int index = tabstrip_->GetModelIndexOfBaseTab(tab); + if (!model_->ContainsIndex(index)) + return false; + + return model_->IsAppTab(index); +} + +bool BrowserTabStripController::IsToolbarVisible(BaseTab* tab) { + int index = tabstrip_->GetModelIndexOfBaseTab(tab); + if (!model_->ContainsIndex(index)) + return false; + + return model_->IsToolbarVisible(index); +} + int BrowserTabStripController::GetCount() const { return model_->count(); } diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.h b/chrome/browser/views/tabs/browser_tab_strip_controller.h index 9f0a7a5..fb79c71 100644 --- a/chrome/browser/views/tabs/browser_tab_strip_controller.h +++ b/chrome/browser/views/tabs/browser_tab_strip_controller.h @@ -35,6 +35,8 @@ class BrowserTabStripController : public TabStripController, void ExecuteCommandForTab(TabStripModel::ContextMenuCommand command_id, BaseTab* tab); bool IsTabPinned(BaseTab* tab); + bool IsAppTab(BaseTab* tab); + bool IsToolbarVisible(BaseTab* tab); // TabStripController implementation: virtual int GetCount() const; diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 4712bd1..03cc42f 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -129,7 +129,8 @@ TabStrip::TabStrip(TabStripController* controller) current_selected_width_(Tab::GetStandardSize().width()), available_width_for_tabs_(-1), in_tab_close_(false), - animation_container_(new AnimationContainer()) { + animation_container_(new AnimationContainer()), + new_tab_button_enabled_(true) { Init(); } @@ -374,9 +375,12 @@ views::View* TabStrip::GetViewByID(int view_id) const { void TabStrip::Layout() { BaseTabStrip::Layout(); - newtab_button_->SetBounds(newtab_button_bounds_); - - SchedulePaint(); + if (new_tab_button_enabled_) { + newtab_button_->SetBounds(newtab_button_bounds_); + newtab_button_->SetVisible(true); + } else { + newtab_button_->SetVisible(false); + } } gfx::Size TabStrip::GetPreferredSize() { diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h index 2620f22..92ba7f9 100644 --- a/chrome/browser/views/tabs/tab_strip.h +++ b/chrome/browser/views/tabs/tab_strip.h @@ -45,6 +45,16 @@ class TabStrip : public BaseTabStrip, explicit TabStrip(TabStripController* controller); virtual ~TabStrip(); + // Set whether the new tab button is enabled. + void set_new_tab_button_enabled(bool enabled) { + new_tab_button_enabled_ = enabled; + } + + // Returns whether the new tab button is enabled. + bool new_tab_button_enabled() { + return new_tab_button_enabled_; + } + // Creates the new tab button. void InitTabStripButtons(); @@ -302,6 +312,9 @@ class TabStrip : public BaseTabStrip, // Used for stage 1 of new tab animation. base::OneShotTimer<TabStrip> new_tab_timer_; + // Whether the new tab button is being displayed. + bool new_tab_button_enabled_; + DISALLOW_COPY_AND_ASSIGN(TabStrip); }; diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc index 8ece2c1..1b7ff8b 100644 --- a/chrome/browser/views/toolbar_view.cc +++ b/chrome/browser/views/toolbar_view.cc @@ -58,6 +58,9 @@ static const int kPopupTopSpacingNonGlass = 3; static const int kPopupBottomSpacingNonGlass = 2; static const int kPopupBottomSpacingGlass = 1; +// The height of the toolbar when it is in collapsed mode. +const int kCollapsedToolbarHeight = 7; + static SkBitmap* kPopupBackgroundEdge = NULL; //////////////////////////////////////////////////////////////////////////////// @@ -76,7 +79,8 @@ ToolbarView::ToolbarView(Browser* browser) browser_(browser), profiles_menu_contents_(NULL), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), - destroyed_flag_(NULL) { + destroyed_flag_(NULL), + collapsed_(false) { SetID(VIEW_ID_TOOLBAR); browser_->command_updater()->AddCommandObserver(IDC_BACK, this); @@ -219,6 +223,22 @@ void ToolbarView::RemoveMenuListener(views::MenuListener* listener) { } } +void ToolbarView::SetCollapsed(bool val) { + if (collapsed_ == val) + return; + + collapsed_ = val; + + // When switching to and from collapsed view, we need to force hide/show the + // location bar entry view, like we do when we switch to full screen mode in + // BrowserView::ProcessFullscreen. Otherwise the text view can appear floating + // on top of web content. + if (collapsed_) + location_bar_->PushForceHidden(); + else + location_bar_->PopForceHidden(); +} + //////////////////////////////////////////////////////////////////////////////// // ToolbarView, AccessibleToolbarView overrides: @@ -396,7 +416,8 @@ gfx::Size ToolbarView::GetPreferredSize() { normal_background = *rb.GetBitmapNamed(IDR_CONTENT_TOP_CENTER); } - return gfx::Size(min_width, normal_background.height()); + return gfx::Size(min_width, + collapsed_ ? kCollapsedToolbarHeight : normal_background.height()); } int vertical_spacing = PopupTopSpacing() + @@ -419,6 +440,10 @@ void ToolbarView::Layout() { return; } + // In collapsed mode, we don't show any of the child controls. + for (int i = 0; i < GetChildViewCount(); ++i) + GetChildViewAt(i)->SetVisible(!collapsed_); + int child_y = std::min(kControlVertOffset, height()); // We assume all child elements are the same height. int child_height = diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h index 83e28f6..5303ba8 100644 --- a/chrome/browser/views/toolbar_view.h +++ b/chrome/browser/views/toolbar_view.h @@ -79,6 +79,8 @@ class ToolbarView : public AccessibleToolbarView, ReloadButton* reload_button() const { return reload_; } LocationBarView* location_bar() const { return location_bar_; } views::MenuButton* app_menu() const { return app_menu_; } + bool collapsed() const { return collapsed_; } + void SetCollapsed(bool val); // Overridden from AccessibleToolbarView virtual bool SetToolbarFocus(int view_storage_id, View* initial_focus); @@ -213,6 +215,9 @@ class ToolbarView : public AccessibleToolbarView, // running. bool* destroyed_flag_; + // When collapsed, the toolbar is just a tiny strip, no controls are visible. + bool collapsed_; + DISALLOW_IMPLICIT_CONSTRUCTORS(ToolbarView); }; |