summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstevet@chromium.org <stevet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-10 19:28:50 +0000
committerstevet@chromium.org <stevet@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-10 19:28:50 +0000
commitb584fb90f233ce696c9e1f26a306e4e13af78a56 (patch)
treeb375031588f8ab04eca6707227774901bac33674
parent08873a8668f8ec74d3f7ccb7f64971b11d57176c (diff)
downloadchromium_src-b584fb90f233ce696c9e1f26a306e4e13af78a56.zip
chromium_src-b584fb90f233ce696c9e1f26a306e4e13af78a56.tar.gz
chromium_src-b584fb90f233ce696c9e1f26a306e4e13af78a56.tar.bz2
The initial prototype code for the compact navigation (cnav) prototype, currently only active in windows. This is well hidden behind a flag and a context menu option.
Loosely based off oshima's original prototype patch: http://codereview.chromium.org/165272 BUG=None TEST=Activate the cnav prototype in about:flags. Right click a tab and select "Hide Toolbar" to go into cnav mode. Ensure that the compact location bar provides the same basic functionality as the toolbar (except browser actions). Review URL: http://codereview.chromium.org/6913026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84831 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/chrome_command_ids.h1
-rw-r--r--chrome/app/generated_resources.grd15
-rw-r--r--chrome/app/theme/theme_resources.grd6
-rw-r--r--chrome/browser/about_flags.cc7
-rw-r--r--chrome/browser/tabs/default_tab_handler.cc8
-rw-r--r--chrome/browser/tabs/default_tab_handler.h2
-rw-r--r--chrome/browser/tabs/tab_strip_model.cc18
-rw-r--r--chrome/browser/tabs/tab_strip_model.h5
-rw-r--r--chrome/browser/tabs/tab_strip_model_delegate.h6
-rw-r--r--chrome/browser/tabs/tab_strip_model_observer.cc4
-rw-r--r--chrome/browser/tabs/tab_strip_model_observer.h4
-rw-r--r--chrome/browser/tabs/tab_strip_model_unittest.cc2
-rw-r--r--chrome/browser/ui/browser.cc36
-rw-r--r--chrome/browser/ui/browser.h10
-rw-r--r--chrome/browser/ui/browser_window.h3
-rw-r--r--chrome/browser/ui/cocoa/browser_window_cocoa.h1
-rw-r--r--chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm4
-rw-r--r--chrome/browser/ui/cocoa/view_id_util_browsertest.mm7
-rw-r--r--chrome/browser/ui/gtk/browser_window_gtk.cc6
-rw-r--r--chrome/browser/ui/gtk/browser_window_gtk.h3
-rw-r--r--chrome/browser/ui/gtk/view_id_util_browsertest.cc5
-rw-r--r--chrome/browser/ui/panels/panel.cc4
-rw-r--r--chrome/browser/ui/panels/panel.h1
-rw-r--r--chrome/browser/ui/panels/panel_browser_window_cocoa.h1
-rw-r--r--chrome/browser/ui/panels/panel_browser_window_cocoa.mm4
-rw-r--r--chrome/browser/ui/tabs/tab_menu_model.cc34
-rw-r--r--chrome/browser/ui/tabs/tab_menu_model.h3
-rw-r--r--chrome/browser/ui/view_ids.h9
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_location_bar_view.cc332
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_location_bar_view.h104
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.cc517
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h138
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_navigation_bar.cc186
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_navigation_bar.h64
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_options_bar.cc151
-rw-r--r--chrome/browser/ui/views/compact_nav/compact_options_bar.h81
-rw-r--r--chrome/browser/ui/views/dropdown_bar_host.cc33
-rw-r--r--chrome/browser/ui/views/dropdown_bar_host.h13
-rw-r--r--chrome/browser/ui/views/dropdown_bar_host_delegate.h21
-rw-r--r--chrome/browser/ui/views/dropdown_bar_view.cc107
-rw-r--r--chrome/browser/ui/views/dropdown_bar_view.h46
-rw-r--r--chrome/browser/ui/views/find_bar_host.cc3
-rw-r--r--chrome/browser/ui/views/find_bar_view.cc47
-rw-r--r--chrome/browser/ui/views/frame/browser_view.cc133
-rw-r--r--chrome/browser/ui/views/frame/browser_view.h44
-rw-r--r--chrome/browser/ui/views/frame/browser_view_layout.cc137
-rw-r--r--chrome/browser/ui/views/frame/browser_view_layout.h11
-rw-r--r--chrome/browser/ui/views/frame/opaque_browser_frame_view.cc37
-rw-r--r--chrome/browser/ui/views/location_bar/location_bar_view.cc12
-rw-r--r--chrome/browser/ui/views/location_bar/location_bar_view.h18
-rw-r--r--chrome/browser/ui/views/tabs/base_tab.cc2
-rw-r--r--chrome/browser/ui/views/tabs/base_tab_strip.cc7
-rw-r--r--chrome/browser/ui/views/tabs/base_tab_strip.h1
-rw-r--r--chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc5
-rw-r--r--chrome/browser/ui/views/tabs/browser_tab_strip_controller.h1
-rw-r--r--chrome/browser/ui/views/tabs/tab_controller.h4
-rw-r--r--chrome/browser/ui/views/tabs/tab_strip_controller.h4
-rw-r--r--chrome/browser/ui/views/toolbar_view.cc110
-rw-r--r--chrome/browser/ui/views/toolbar_view.h8
-rw-r--r--chrome/chrome_browser.gypi19
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/pref_names.cc3
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--chrome/test/test_browser_window.h4
-rw-r--r--views/events/event.h5
-rw-r--r--views/events/event_win.cc28
67 files changed, 2454 insertions, 197 deletions
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index b269d83..a9cabbf 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -53,6 +53,7 @@
#define IDC_TOGGLE_VERTICAL_TABS 34034
#define IDC_SEARCH 34035
#define IDC_TABPOSE 34036
+#define IDC_COMPACT_NAVBAR 34037
// Page-related commands
#define IDC_BOOKMARK_PAGE 35000
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index b946546..c636d04 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4198,6 +4198,15 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_FLAGS_DISABLE_INTERACTIVE_FORM_VALIDATION_DESCRIPTION" desc="Description of the 'Disable HTML5 interactive form validation' lab.">
Disable showing validation messages and preventing form submission.
</message>
+ <message name="IDS_FLAGS_ENABLE_COMPACT_NAVIGATION" desc="Name of the 'Compact Navigation' lab.">
+ Compact Navigation
+ </message>
+ <message name="IDS_FLAGS_ENABLE_COMPACT_NAVIGATION_DESCRIPTION" desc="Description of the 'Compact Navigation' lab.">
+ Adds a "Hide the toolbar" entry to the tabstrip's context menu. Use this to toggle between always displaying the toolbar (default) and only opening it as a drop down box as needed.
+ </message>
+ <message name="IDS_COMPACT_NAVIGATION_BAR" desc="The menu item on the app menu to toggle compact navigation bar">
+ Compact Navigation Bar
+ </message>
<message name="IDS_FLAGS_ENABLE_HISTORY_QUICK_PROVIDER" desc="Name of the 'Enable better visit history matching in the omnibox' lab.">
Better omnibox history matching
</message>
@@ -5699,6 +5708,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_TAB_CXMENU_USE_VERTICAL_TABS" desc="Use the vertical tab strip">
Use side tabs
</message>
+ <message name="IDS_TAB_CXMENU_USE_COMPACT_NAVIGATION_BAR" desc="Hide the toolbar so that we use the compact navigation bar instead">
+ Hide the toolbar
+ </message>
<message name="IDS_TAB_CXMENU_SELECT_BY_DOMAIN" desc="The label of the tab context menu item for selecting tabs with the same domain">
Select by domain
</message>
@@ -5746,6 +5758,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_TAB_CXMENU_USE_VERTICAL_TABS" desc="In Title Case: Use the vertical tab strip">
Use Side Tabs
</message>
+ <message name="IDS_TAB_CXMENU_USE_COMPACT_NAVIGATION_BAR" desc="In Title Case: Hide the toolbar so that we use the compact navigation bar instead">
+ Hide The Toolbar
+ </message>
<message name="IDS_TAB_CXMENU_SELECT_BY_DOMAIN" desc="The label of the tab context menu item for selecting tabs with the same domain">
Select by Domain
</message>
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 4696db8..cee7dec 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -38,6 +38,12 @@
<include name="IDR_BOOKMARK_BAR_FOLDER" file="bookmark_bar_folder_mac.png" type="BINDATA" />
</if>
<include name="IDR_CLOSE_BUTTON_MASK" file="close_button_mask.png" type="BINDATA" />
+ <include name="IDR_CNAV_DIALOG_LEFT" file="cnav_dialog_left.png" type="BINDATA" />
+ <include name="IDR_CNAV_DIALOG_MIDDLE" file="cnav_dialog_middle.png" type="BINDATA" />
+ <include name="IDR_CNAV_DIALOG_RIGHT" file="cnav_dialog_right.png" type="BINDATA" />
+ <include name="IDR_COMPACTNAV_BACK" file="compactnav_back.png" type="BINDATA" />
+ <include name="IDR_COMPACTNAV_FORWARD" file="compactnav_forward.png" type="BINDATA" />
+ <include name="IDR_COMPACTNAV_SEPARATOR" file="compactnav_separator.png" type="BINDATA" />
<if expr="os.find('win') != -1">
<include name="IDR_CONFLICT_BADGE" file="conflict_badge.png" type="BINDATA" />
<include name="IDR_CONFLICT_MENU" file="conflict_menu.png" type="BINDATA" />
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 7cd7eee..dce9ec2 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -249,6 +249,13 @@ const Experiment kExperiments[] = {
SINGLE_VALUE_TYPE(switches::kFocusExistingTabOnOpen)
},
{
+ "compact-navigation",
+ IDS_FLAGS_ENABLE_COMPACT_NAVIGATION,
+ IDS_FLAGS_ENABLE_COMPACT_NAVIGATION_DESCRIPTION,
+ kOsWin, // TODO(stevet): Add other platforms when ready.
+ SINGLE_VALUE_TYPE(switches::kEnableCompactNavigation)
+ },
+ {
"new-tab-page-4",
IDS_FLAGS_NEW_TAB_PAGE_4_NAME,
IDS_FLAGS_NEW_TAB_PAGE_4_DESCRIPTION,
diff --git a/chrome/browser/tabs/default_tab_handler.cc b/chrome/browser/tabs/default_tab_handler.cc
index b81f0a2..1524852 100644
--- a/chrome/browser/tabs/default_tab_handler.cc
+++ b/chrome/browser/tabs/default_tab_handler.cc
@@ -115,6 +115,10 @@ void DefaultTabHandler::ToggleUseVerticalTabs() {
delegate_->AsBrowser()->ToggleUseVerticalTabs();
}
+void DefaultTabHandler::ToggleUseCompactNavigationBar() {
+ delegate_->AsBrowser()->ToggleUseCompactNavigationBar();
+}
+
bool DefaultTabHandler::CanRestoreTab() {
return delegate_->AsBrowser()->CanRestoreTab();
}
@@ -131,6 +135,10 @@ bool DefaultTabHandler::UseVerticalTabs() const {
return delegate_->AsBrowser()->UseVerticalTabs();
}
+bool DefaultTabHandler::UseCompactNavigationBar() const {
+ return delegate_->AsBrowser()->UseCompactNavigationBar();
+}
+
////////////////////////////////////////////////////////////////////////////////
// DefaultTabHandler, TabStripModelObserver implementation:
diff --git a/chrome/browser/tabs/default_tab_handler.h b/chrome/browser/tabs/default_tab_handler.h
index 09f779a..f59dd25 100644
--- a/chrome/browser/tabs/default_tab_handler.h
+++ b/chrome/browser/tabs/default_tab_handler.h
@@ -52,10 +52,12 @@ class DefaultTabHandler : public TabHandler,
virtual void BookmarkAllTabs();
virtual bool CanCloseTab() const;
virtual void ToggleUseVerticalTabs();
+ virtual void ToggleUseCompactNavigationBar();
virtual bool CanRestoreTab();
virtual void RestoreTab();
virtual bool LargeIconsPermitted() const;
virtual bool UseVerticalTabs() const;
+ virtual bool UseCompactNavigationBar() const;
// Overridden from TabStripModelObserver:
virtual void TabInsertedAt(TabContentsWrapper* contents,
diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc
index fa632af..d1ded2f 100644
--- a/chrome/browser/tabs/tab_strip_model.cc
+++ b/chrome/browser/tabs/tab_strip_model.cc
@@ -711,6 +711,10 @@ void TabStripModel::MoveTabPrevious() {
MoveTabContentsAt(active_index(), new_index, true);
}
+void TabStripModel::ActiveTabClicked(int index) {
+ FOR_EACH_OBSERVER(TabStripModelObserver, observers_, ActiveTabClicked(index));
+}
+
// Context menu functions.
bool TabStripModel::IsContextMenuCommandEnabled(
int context_index, ContextMenuCommand command_id) const {
@@ -764,6 +768,7 @@ bool TabStripModel::IsContextMenuCommandEnabled(
delegate_->CanBookmarkAllTabs();
case CommandUseVerticalTabs:
+ case CommandUseCompactNavigationBar:
return true;
case CommandSelectByDomain:
@@ -782,6 +787,8 @@ bool TabStripModel::IsContextMenuCommandChecked(
switch (command_id) {
case CommandUseVerticalTabs:
return delegate()->UseVerticalTabs();
+ case CommandUseCompactNavigationBar:
+ return delegate()->UseCompactNavigationBar();
default:
NOTREACHED();
break;
@@ -904,6 +911,14 @@ void TabStripModel::ExecuteContextMenuCommand(
break;
}
+ case CommandUseCompactNavigationBar: {
+ UserMetrics::RecordAction(
+ UserMetricsAction("TabContextMenu_CompactNavigationBar"));
+
+ delegate()->ToggleUseCompactNavigationBar();
+ break;
+ }
+
case CommandSelectByDomain:
case CommandSelectByOpener: {
std::vector<int> indices;
@@ -1029,6 +1044,9 @@ bool TabStripModel::ContextMenuCommandToBrowserCommand(int cmd_id,
case CommandUseVerticalTabs:
*browser_cmd = IDC_TOGGLE_VERTICAL_TABS;
break;
+ case CommandUseCompactNavigationBar:
+ *browser_cmd = IDC_COMPACT_NAVBAR;
+ break;
default:
*browser_cmd = 0;
return false;
diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h
index f236e5f..c0d1e0b 100644
--- a/chrome/browser/tabs/tab_strip_model.h
+++ b/chrome/browser/tabs/tab_strip_model.h
@@ -411,6 +411,10 @@ class TabStripModel : public NotificationObserver {
void MoveTabNext();
void MoveTabPrevious();
+ // Notifies the observers that the active/foreground tab at |index| was
+ // reselected (ie - it was already active and was clicked again).
+ void ActiveTabClicked(int index);
+
// View API //////////////////////////////////////////////////////////////////
// Context menu functions.
@@ -426,6 +430,7 @@ class TabStripModel : public NotificationObserver {
CommandTogglePinned,
CommandBookmarkAllTabs,
CommandUseVerticalTabs,
+ CommandUseCompactNavigationBar,
CommandSelectByDomain,
CommandSelectByOpener,
CommandLast
diff --git a/chrome/browser/tabs/tab_strip_model_delegate.h b/chrome/browser/tabs/tab_strip_model_delegate.h
index bae327e..0279e84 100644
--- a/chrome/browser/tabs/tab_strip_model_delegate.h
+++ b/chrome/browser/tabs/tab_strip_model_delegate.h
@@ -118,6 +118,12 @@ class TabStripModelDelegate {
// Toggles the use of the vertical tabstrip.
virtual void ToggleUseVerticalTabs() = 0;
+ // Returns true if the compact navigation bar should be used.
+ virtual bool UseCompactNavigationBar() const = 0;
+
+ // Toggles the use of the compact navigation bar.
+ virtual void ToggleUseCompactNavigationBar() = 0;
+
// Returns true if the tab strip can use large icons.
virtual bool LargeIconsPermitted() const = 0;
diff --git a/chrome/browser/tabs/tab_strip_model_observer.cc b/chrome/browser/tabs/tab_strip_model_observer.cc
index f20746a..0f5395b 100644
--- a/chrome/browser/tabs/tab_strip_model_observer.cc
+++ b/chrome/browser/tabs/tab_strip_model_observer.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -58,3 +58,5 @@ void TabStripModelObserver::TabBlockedStateChanged(TabContentsWrapper* contents,
void TabStripModelObserver::TabStripEmpty() {}
void TabStripModelObserver::TabStripModelDeleted() {}
+
+void TabStripModelObserver::ActiveTabClicked(int index) {}
diff --git a/chrome/browser/tabs/tab_strip_model_observer.h b/chrome/browser/tabs/tab_strip_model_observer.h
index af169ea..ba9df25 100644
--- a/chrome/browser/tabs/tab_strip_model_observer.h
+++ b/chrome/browser/tabs/tab_strip_model_observer.h
@@ -127,6 +127,10 @@ class TabStripModelObserver {
// must be dropped.
virtual void TabStripModelDeleted();
+ // Invoked when an active/selected tab at |index| is selected again (ie - the
+ // active/foreground tab is clicked).
+ virtual void ActiveTabClicked(int index);
+
protected:
virtual ~TabStripModelObserver() {}
};
diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc
index 4876c81..fc1c941 100644
--- a/chrome/browser/tabs/tab_strip_model_unittest.cc
+++ b/chrome/browser/tabs/tab_strip_model_unittest.cc
@@ -130,6 +130,8 @@ class TabStripDummyDelegate : public TabStripModelDelegate {
virtual bool CanCloseTab() const { return true; }
virtual bool UseVerticalTabs() const { return false; }
virtual void ToggleUseVerticalTabs() {}
+ virtual bool UseCompactNavigationBar() const { return false; }
+ virtual void ToggleUseCompactNavigationBar() {}
virtual bool LargeIconsPermitted() const { return true; }
private:
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 74acb11..ab07046 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -264,12 +264,22 @@ Browser::Browser(Type type, Profile* profile)
encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
profile_->GetPrefs(), NULL);
use_vertical_tabs_.Init(prefs::kUseVerticalTabs, profile_->GetPrefs(), this);
+ use_compact_navigation_bar_.Init(prefs::kUseCompactNavigationBar,
+ profile_->GetPrefs(),
+ this);
if (!TabMenuModel::AreVerticalTabsEnabled()) {
// If vertical tabs aren't enabled, explicitly turn them off. Otherwise we
// might show vertical tabs but not show an option to turn them off.
use_vertical_tabs_.SetValue(false);
}
+ if (!TabMenuModel::IsCompactNavigationModeEnabled()) {
+ // If the compact navigation bar isn't enabled, explicitly turn it off.
+ // Otherwise we might show the compact navigation bar but not show an option
+ // to turn it off.
+ use_compact_navigation_bar_.SetValue(false);
+ }
+
UpdateTabStripModelInsertionPolicy();
tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile);
@@ -328,6 +338,7 @@ Browser::~Browser() {
encoding_auto_detect_.Destroy();
use_vertical_tabs_.Destroy();
+ use_compact_navigation_bar_.Destroy();
if (profile_->IsOffTheRecord() &&
!BrowserList::IsOffTheRecordSessionActive()) {
@@ -427,6 +438,11 @@ void Browser::InitBrowserWindow() {
Source<Browser>(this),
NotificationService::NoDetails());
+ if (use_compact_navigation_bar_.GetValue()) {
+ // This enables the compact navigation bar host.
+ UseCompactNavigationBarChanged();
+ }
+
// Show the First Run information bubble if we've been told to.
PrefService* local_state = g_browser_process->local_state();
if (!local_state)
@@ -1216,6 +1232,7 @@ void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) {
command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui);
command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui);
command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, show_main_ui);
+ command_updater_.UpdateCommandEnabled(IDC_COMPACT_NAVBAR, show_main_ui);
#if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC)
command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui);
#endif
@@ -1253,6 +1270,10 @@ void Browser::UseVerticalTabsChanged() {
window()->ToggleTabStripMode();
}
+void Browser::UseCompactNavigationBarChanged() {
+ window_->ToggleUseCompactNavigationBar();
+}
+
bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
bool check_fullscreen) const {
// On Mac, fullscreen mode has most normal things (in a slide-down panel). On
@@ -2150,6 +2171,9 @@ void Browser::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterBooleanPref(prefs::kUseVerticalTabs,
false,
PrefService::UNSYNCABLE_PREF);
+ prefs->RegisterBooleanPref(prefs::kUseCompactNavigationBar,
+ false,
+ PrefService::UNSYNCABLE_PREF);
prefs->RegisterBooleanPref(prefs::kEnableTranslate,
true,
PrefService::SYNCABLE_PREF);
@@ -2299,6 +2323,7 @@ void Browser::ExecuteCommandWithDisposition(
case IDC_FULLSCREEN: ToggleFullscreenMode(); break;
case IDC_EXIT: Exit(); break;
case IDC_TOGGLE_VERTICAL_TABS: ToggleUseVerticalTabs(); break;
+ case IDC_COMPACT_NAVBAR: ToggleUseCompactNavigationBar(); break;
#if defined(OS_CHROMEOS)
case IDC_SEARCH: Search(); break;
case IDC_SHOW_KEYBOARD_OVERLAY: ShowKeyboardOverlay(); break;
@@ -2774,6 +2799,11 @@ void Browser::ToggleUseVerticalTabs() {
UseVerticalTabsChanged();
}
+void Browser::ToggleUseCompactNavigationBar() {
+ use_compact_navigation_bar_.SetValue(!UseCompactNavigationBar());
+ UseCompactNavigationBarChanged();
+}
+
bool Browser::LargeIconsPermitted() const {
// We don't show the big icons in tabs for TYPE_EXTENSION_APP windows because
// for those windows, we already have a big icon in the top-left outside any
@@ -3158,6 +3188,10 @@ bool Browser::UseVerticalTabs() const {
return use_vertical_tabs_.GetValue();
}
+bool Browser::UseCompactNavigationBar() const {
+ return use_compact_navigation_bar_.GetValue();
+}
+
void Browser::ContentsZoomChange(bool zoom_in) {
ExecuteCommand(zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS);
}
@@ -3555,6 +3589,8 @@ void Browser::Observe(NotificationType type,
const std::string& pref_name = *Details<std::string>(details).ptr();
if (pref_name == prefs::kUseVerticalTabs) {
UseVerticalTabsChanged();
+ } else if (pref_name == prefs::kUseCompactNavigationBar) {
+ UseCompactNavigationBarChanged();
} else if (pref_name == prefs::kPrintingEnabled) {
UpdatePrintingState(GetContentRestrictionsForSelectedTab());
} else if (pref_name == prefs::kInstantEnabled) {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index a112030..79b1461d 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -485,7 +485,6 @@ class Browser : public TabHandlerDelegate,
void ToggleFullscreenMode();
void Exit();
#if defined(OS_CHROMEOS)
- void ToggleCompactNavigationBar();
void Search();
void ShowKeyboardOverlay();
#endif
@@ -583,6 +582,7 @@ class Browser : public TabHandlerDelegate,
// Overridden from TabStripModelDelegate:
virtual bool UseVerticalTabs() const;
+ virtual bool UseCompactNavigationBar() const;
/////////////////////////////////////////////////////////////////////////////
@@ -704,6 +704,7 @@ class Browser : public TabHandlerDelegate,
virtual void BookmarkAllTabs();
virtual bool CanCloseTab() const;
virtual void ToggleUseVerticalTabs();
+ virtual void ToggleUseCompactNavigationBar();
virtual bool CanRestoreTab();
virtual void RestoreTab();
virtual bool LargeIconsPermitted() const;
@@ -1029,6 +1030,10 @@ class Browser : public TabHandlerDelegate,
// policy of the tab strip model and notifies the window.
void UseVerticalTabsChanged();
+ // Invoked when the use of the compact navigation bar preference changes.
+ // Notifies the window.
+ void UseCompactNavigationBarChanged();
+
// Implementation of SupportsWindowFeature and CanSupportWindowFeature. If
// |check_fullscreen| is true, the set of features reflect the actual state of
// the browser, otherwise the set of features reflect the possible state of
@@ -1192,6 +1197,9 @@ class Browser : public TabHandlerDelegate,
// Tracks the display mode of the tabstrip.
mutable BooleanPrefMember use_vertical_tabs_;
+ // Tracks the display mode of the navigation bar.
+ mutable BooleanPrefMember use_compact_navigation_bar_;
+
// The profile's tab restore service. The service is owned by the profile,
// and we install ourselves as an observer.
TabRestoreService* tab_restore_service_;
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index ec2f091..8bb212d 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -299,6 +299,9 @@ class BrowserWindow {
virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile,
const Extension* app) = 0;
+ // Toggles compact navigation bar.
+ virtual void ToggleUseCompactNavigationBar() = 0;
+
// Clipboard commands applied to the whole browser window.
virtual void Cut() = 0;
virtual void Copy() = 0;
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa.h b/chrome/browser/ui/cocoa/browser_window_cocoa.h
index 50063c68..3d6a5f5 100644
--- a/chrome/browser/ui/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/ui/cocoa/browser_window_cocoa.h
@@ -104,6 +104,7 @@ class BrowserWindowCocoa : public BrowserWindow,
virtual void Copy();
virtual void Paste();
virtual void ToggleTabStripMode();
+ virtual void ToggleUseCompactNavigationBar() {}
virtual void OpenTabpose();
virtual void PrepareForInstant();
virtual void ShowInstant(TabContentsWrapper* preview);
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
index 59c7757..011a4f6 100644
--- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller_unittest.mm
@@ -92,6 +92,10 @@ class TestTabStripDelegate : public TabStripModelDelegate {
virtual void ToggleUseVerticalTabs() {}
+ virtual bool UseCompactNavigationBar() const { return false; }
+
+ virtual void ToggleUseCompactNavigationBar() {}
+
virtual bool LargeIconsPermitted() const { return true; }
};
diff --git a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
index 8d10b4c..959c4e6 100644
--- a/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
+++ b/chrome/browser/ui/cocoa/view_id_util_browsertest.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -72,7 +72,10 @@ class ViewIDTest : public InProcessBrowserTest {
i == VIEW_ID_AUTOCOMPLETE ||
i == VIEW_ID_CONTENTS_SPLIT ||
i == VIEW_ID_SIDE_BAR_SPLIT ||
- i == VIEW_ID_FEEDBACK_BUTTON) {
+ i == VIEW_ID_FEEDBACK_BUTTON ||
+ i == VIEW_ID_COMPACT_NAV_BAR ||
+ i == VIEW_ID_COMPACT_OPT_BAR ||
+ i == VIEW_ID_COMPACT_NAV_BAR_SPACER) {
continue;
}
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc
index 36bc6fa..0e1d842 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.cc
+++ b/chrome/browser/ui/gtk/browser_window_gtk.cc
@@ -1088,6 +1088,12 @@ void BrowserWindowGtk::Paste() {
gtk_util::DoPaste(this);
}
+void BrowserWindowGtk::ToggleTabStripMode() {
+}
+
+void BrowserWindowGtk::ToggleUseCompactNavigationBar() {
+}
+
void BrowserWindowGtk::PrepareForInstant() {
TabContentsWrapper* contents = contents_container_->tab();
if (contents)
diff --git a/chrome/browser/ui/gtk/browser_window_gtk.h b/chrome/browser/ui/gtk/browser_window_gtk.h
index 44ef7f0..537584b 100644
--- a/chrome/browser/ui/gtk/browser_window_gtk.h
+++ b/chrome/browser/ui/gtk/browser_window_gtk.h
@@ -127,7 +127,8 @@ class BrowserWindowGtk : public BrowserWindow,
virtual void Cut();
virtual void Copy();
virtual void Paste();
- virtual void ToggleTabStripMode() {}
+ virtual void ToggleTabStripMode();
+ virtual void ToggleUseCompactNavigationBar();
virtual void PrepareForInstant();
virtual void ShowInstant(TabContentsWrapper* preview);
virtual void HideInstant(bool instant_is_active);
diff --git a/chrome/browser/ui/gtk/view_id_util_browsertest.cc b/chrome/browser/ui/gtk/view_id_util_browsertest.cc
index 64b9389..83ec15f 100644
--- a/chrome/browser/ui/gtk/view_id_util_browsertest.cc
+++ b/chrome/browser/ui/gtk/view_id_util_browsertest.cc
@@ -41,7 +41,10 @@ IN_PROC_BROWSER_TEST_F(ViewIDTest, Basic) {
i == VIEW_ID_TAB ||
i == VIEW_ID_SIDE_BAR_CONTAINER ||
i == VIEW_ID_SIDE_BAR_SPLIT ||
- i == VIEW_ID_FEEDBACK_BUTTON) {
+ i == VIEW_ID_FEEDBACK_BUTTON ||
+ i == VIEW_ID_COMPACT_NAV_BAR ||
+ i == VIEW_ID_COMPACT_OPT_BAR ||
+ i == VIEW_ID_COMPACT_NAV_BAR_SPACER) {
continue;
}
diff --git a/chrome/browser/ui/panels/panel.cc b/chrome/browser/ui/panels/panel.cc
index b8b5897..9b433a3 100644
--- a/chrome/browser/ui/panels/panel.cc
+++ b/chrome/browser/ui/panels/panel.cc
@@ -307,6 +307,10 @@ void Panel::ShowCreateChromeAppShortcutsDialog(Profile* profile,
NOTIMPLEMENTED();
}
+void Panel::ToggleUseCompactNavigationBar() {
+ NOTIMPLEMENTED();
+}
+
void Panel::Cut() {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/ui/panels/panel.h b/chrome/browser/ui/panels/panel.h
index 1e997ca..4fe4480 100644
--- a/chrome/browser/ui/panels/panel.h
+++ b/chrome/browser/ui/panels/panel.h
@@ -111,6 +111,7 @@ class Panel : public BrowserWindow {
TabContentsWrapper* tab_contents) OVERRIDE;
virtual void ShowCreateChromeAppShortcutsDialog(
Profile* profile, const Extension* app) OVERRIDE;
+ virtual void ToggleUseCompactNavigationBar();
virtual void Cut() OVERRIDE;
virtual void Copy() OVERRIDE;
virtual void Paste() OVERRIDE;
diff --git a/chrome/browser/ui/panels/panel_browser_window_cocoa.h b/chrome/browser/ui/panels/panel_browser_window_cocoa.h
index e9e4484..3ccc106 100644
--- a/chrome/browser/ui/panels/panel_browser_window_cocoa.h
+++ b/chrome/browser/ui/panels/panel_browser_window_cocoa.h
@@ -97,6 +97,7 @@ class PanelBrowserWindowCocoa : public BrowserWindow {
virtual void Copy() OVERRIDE;
virtual void Paste() OVERRIDE;
virtual void ToggleTabStripMode() OVERRIDE;
+ virtual void ToggleUseCompactNavigationBar() OVERRIDE;
virtual void OpenTabpose() OVERRIDE;
virtual void PrepareForInstant() OVERRIDE;
virtual void ShowInstant(TabContentsWrapper* preview) OVERRIDE;
diff --git a/chrome/browser/ui/panels/panel_browser_window_cocoa.mm b/chrome/browser/ui/panels/panel_browser_window_cocoa.mm
index fe8e7b8..58a019d 100644
--- a/chrome/browser/ui/panels/panel_browser_window_cocoa.mm
+++ b/chrome/browser/ui/panels/panel_browser_window_cocoa.mm
@@ -334,6 +334,10 @@ void PanelBrowserWindowCocoa::ToggleTabStripMode() {
NOTIMPLEMENTED();
}
+void PanelBrowserWindowCocoa::ToggleUseCompactNavigationBar() {
+ NOTIMPLEMENTED();
+}
+
#if defined(OS_MACOSX)
void PanelBrowserWindowCocoa::OpenTabpose() {
NOTIMPLEMENTED();
diff --git a/chrome/browser/ui/tabs/tab_menu_model.cc b/chrome/browser/ui/tabs/tab_menu_model.cc
index 28b58f5..4e89731 100644
--- a/chrome/browser/ui/tabs/tab_menu_model.cc
+++ b/chrome/browser/ui/tabs/tab_menu_model.cc
@@ -32,6 +32,16 @@ bool TabMenuModel::AreVerticalTabsEnabled() {
#endif
}
+bool TabMenuModel::IsCompactNavigationModeEnabled() {
+#if defined(TOOLKIT_VIEWS)
+ return CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableCompactNavigation);
+#else
+ return false;
+#endif
+}
+
+
void TabMenuModel::Build(bool is_pinned) {
AddItemWithStringId(TabStripModel::CommandNewTab, IDS_TAB_CXMENU_NEWTAB);
AddSeparator();
@@ -52,10 +62,16 @@ void TabMenuModel::Build(bool is_pinned) {
AddItemWithStringId(TabStripModel::CommandRestoreTab, IDS_RESTORE_TAB);
AddItemWithStringId(TabStripModel::CommandBookmarkAllTabs,
IDS_TAB_CXMENU_BOOKMARK_ALL_TABS);
- if (AreVerticalTabsEnabled()) {
+ if (AreVerticalTabsEnabled() || IsCompactNavigationModeEnabled()) {
AddSeparator();
- AddCheckItemWithStringId(TabStripModel::CommandUseVerticalTabs,
- IDS_TAB_CXMENU_USE_VERTICAL_TABS);
+ if (AreVerticalTabsEnabled()) {
+ AddCheckItemWithStringId(TabStripModel::CommandUseVerticalTabs,
+ IDS_TAB_CXMENU_USE_VERTICAL_TABS);
+ }
+ if (IsCompactNavigationModeEnabled()) {
+ AddCheckItemWithStringId(TabStripModel::CommandUseCompactNavigationBar,
+ IDS_TAB_CXMENU_USE_COMPACT_NAVIGATION_BAR);
+ }
}
}
@@ -94,10 +110,16 @@ void TabMenuModel::Build(TabStripModel* tab_strip, int index) {
AddItemWithStringId(TabStripModel::CommandRestoreTab, IDS_RESTORE_TAB);
AddItemWithStringId(TabStripModel::CommandBookmarkAllTabs,
IDS_TAB_CXMENU_BOOKMARK_ALL_TABS);
- if (AreVerticalTabsEnabled()) {
+ if (AreVerticalTabsEnabled() || IsCompactNavigationModeEnabled()) {
AddSeparator();
- AddCheckItemWithStringId(TabStripModel::CommandUseVerticalTabs,
- IDS_TAB_CXMENU_USE_VERTICAL_TABS);
+ if (AreVerticalTabsEnabled()) {
+ AddCheckItemWithStringId(TabStripModel::CommandUseVerticalTabs,
+ IDS_TAB_CXMENU_USE_VERTICAL_TABS);
+ }
+ if (IsCompactNavigationModeEnabled()) {
+ AddCheckItemWithStringId(TabStripModel::CommandUseCompactNavigationBar,
+ IDS_TAB_CXMENU_USE_COMPACT_NAVIGATION_BAR);
+ }
}
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableTabGroupsContextMenu)) {
diff --git a/chrome/browser/ui/tabs/tab_menu_model.h b/chrome/browser/ui/tabs/tab_menu_model.h
index 7d4d952..234a201 100644
--- a/chrome/browser/ui/tabs/tab_menu_model.h
+++ b/chrome/browser/ui/tabs/tab_menu_model.h
@@ -25,6 +25,9 @@ class TabMenuModel : public ui::SimpleMenuModel {
// Returns true if vertical tabs are enabled.
static bool AreVerticalTabsEnabled();
+ // Returns true if compact navigation bar is enabled.
+ static bool IsCompactNavigationModeEnabled();
+
private:
// TODO: nuke this when first constructor is removed.
void Build(bool is_pinned);
diff --git a/chrome/browser/ui/view_ids.h b/chrome/browser/ui/view_ids.h
index 3df052d..e7199fe 100644
--- a/chrome/browser/ui/view_ids.h
+++ b/chrome/browser/ui/view_ids.h
@@ -78,6 +78,15 @@ enum ViewID {
// The sidebar split.
VIEW_ID_SIDE_BAR_SPLIT,
+ // The Compact Navigation bar.
+ VIEW_ID_COMPACT_NAV_BAR,
+
+ // The Compact Options bar.
+ VIEW_ID_COMPACT_OPT_BAR,
+
+ // The spacer for the compact navigation bar.
+ VIEW_ID_COMPACT_NAV_BAR_SPACER,
+
// Used in chrome/browser/ui/gtk/view_id_util_browsertests.cc
// If you add new ids, make sure the above test passes.
VIEW_ID_PREDEFINED_COUNT
diff --git a/chrome/browser/ui/views/compact_nav/compact_location_bar_view.cc b/chrome/browser/ui/views/compact_nav/compact_location_bar_view.cc
new file mode 100644
index 0000000..f4c0d18
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_location_bar_view.cc
@@ -0,0 +1,332 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view.h"
+
+#if defined(TOOLKIT_USES_GTK)
+#include <gtk/gtk.h>
+#endif
+
+#include <algorithm>
+
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
+#include "chrome/browser/bookmarks/bookmark_model.h"
+#include "chrome/browser/favicon/favicon_tab_helper.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/themes/theme_service.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/browser/ui/view_ids.h"
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h"
+#include "chrome/browser/ui/views/event_utils.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+#include "chrome/browser/ui/views/reload_button.h"
+#include "content/browser/user_metrics.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "grit/theme_resources_standard.h"
+#include "ui/base/accessibility/accessible_view_state.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/theme_provider.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/point.h"
+#include "views/background.h"
+#include "views/controls/button/image_button.h"
+#include "views/controls/native/native_view_host.h"
+#include "views/widget/widget.h"
+#include "views/window/window.h"
+
+namespace {
+
+const int kDefaultLocationEntryWidth = 375;
+const int kCompactLocationLeftMargin = 7;
+const int kCompactLocationRightMargin = 8;
+const int kEntryPadding = 2;
+// TODO(oshima): ToolbarView gets this from background image's height;
+// Find out the right way, value for compact location bar.
+const int kDefaultLocationBarHeight = 34;
+
+} // namespace
+
+CompactLocationBarView::CompactLocationBarView(CompactLocationBarViewHost* host)
+ : DropdownBarView(host),
+ reload_button_(NULL),
+ location_bar_view_(NULL),
+ initialized_(false) {
+ SetFocusable(true);
+}
+
+CompactLocationBarView::~CompactLocationBarView() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarView public:
+
+void CompactLocationBarView::SetFocusAndSelection(bool select_all) {
+ location_bar_view_->FocusLocation(select_all);
+}
+
+void CompactLocationBarView::Update(const TabContents* contents) {
+ location_bar_view_->Update(contents);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AccessiblePaneView overrides:
+
+bool CompactLocationBarView::SetPaneFocus(
+ int view_storage_id, views::View* initial_focus) {
+ if (!AccessiblePaneView::SetPaneFocus(view_storage_id, initial_focus))
+ return false;
+
+ location_bar_view_->SetShowFocusRect(true);
+ return true;
+}
+
+void CompactLocationBarView::GetAccessibleState(
+ ui::AccessibleViewState* state) {
+ state->role = ui::AccessibilityTypes::ROLE_TOOLBAR;
+ state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_TOOLBAR);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarView private:
+
+Browser* CompactLocationBarView::browser() const {
+ return host()->browser_view()->browser();
+}
+
+void CompactLocationBarView::Init() {
+ DCHECK(!initialized_);
+ initialized_ = true;
+
+ // Use a larger version of the system font.
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ font_ = rb.GetFont(ResourceBundle::MediumFont);
+
+ // Location bar.
+ location_bar_view_ = new LocationBarView(
+ browser()->profile(),
+ browser()->command_updater(),
+ browser()->toolbar_model(),
+ clb_host(),
+ LocationBarView::NORMAL);
+
+ // Reload button.
+ reload_button_ = new ReloadButton(location_bar_view_, browser());
+ reload_button_->set_triggerable_event_flags(ui::EF_LEFT_BUTTON_DOWN |
+ ui::EF_MIDDLE_BUTTON_DOWN);
+ reload_button_->set_tag(IDC_RELOAD);
+ reload_button_->SetTooltipText(
+ UTF16ToWide(l10n_util::GetStringUTF16(IDS_TOOLTIP_RELOAD)));
+ reload_button_->SetAccessibleName(
+ l10n_util::GetStringUTF16(IDS_ACCNAME_RELOAD));
+ reload_button_->SetID(VIEW_ID_RELOAD_BUTTON);
+
+ ThemeProvider* tp = GetThemeProvider();
+ reload_button_->SetImage(views::CustomButton::BS_NORMAL,
+ tp->GetBitmapNamed(IDR_RELOAD));
+ reload_button_->SetImage(views::CustomButton::BS_HOT,
+ tp->GetBitmapNamed(IDR_RELOAD_H));
+ reload_button_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_RELOAD_P));
+ reload_button_->SetToggledImage(views::CustomButton::BS_NORMAL,
+ tp->GetBitmapNamed(IDR_STOP));
+ reload_button_->SetToggledImage(views::CustomButton::BS_HOT,
+ tp->GetBitmapNamed(IDR_STOP_H));
+ reload_button_->SetToggledImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_STOP_P));
+ reload_button_->SetToggledImage(views::CustomButton::BS_DISABLED,
+ tp->GetBitmapNamed(IDR_STOP_D));
+
+ // Always add children in order from left to right, for accessibility.
+ AddChildView(reload_button_);
+ AddChildView(location_bar_view_);
+ location_bar_view_->Init();
+
+ SetDialogBorderBitmaps(rb.GetBitmapNamed(IDR_CNAV_DIALOG_LEFT),
+ rb.GetBitmapNamed(IDR_CNAV_DIALOG_MIDDLE),
+ rb.GetBitmapNamed(IDR_CNAV_DIALOG_RIGHT));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// views::View overrides:
+
+gfx::Size CompactLocationBarView::GetPreferredSize() {
+ if (!reload_button_)
+ return gfx::Size(); // Not initialized yet, do nothing.
+
+ gfx::Size reload_size = reload_button_->GetPreferredSize();
+ gfx::Size location_size = location_bar_view_->GetPreferredSize();
+ int width = kCompactLocationLeftMargin + reload_size.width() +
+ std::max(kDefaultLocationEntryWidth,
+ location_bar_view_->GetPreferredSize().width()) +
+ kCompactLocationRightMargin;
+ return gfx::Size(width, kDefaultLocationBarHeight);
+}
+
+void CompactLocationBarView::OnPaint(gfx::Canvas* canvas) {
+ // TODO(stevet): A lot of this method is copied almost directly from
+ // FindBarView. Perhaps we can share it in the common parent class.
+ SkPaint paint;
+
+ gfx::Rect bounds = PaintOffsetToolbarBackground(canvas);
+
+ // Now flip the canvas for the rest of the graphics if in RTL mode.
+ canvas->Save();
+ if (base::i18n::IsRTL()) {
+ canvas->TranslateInt(width(), 0);
+ canvas->ScaleInt(-1, 1);
+ }
+
+ PaintDialogBorder(canvas, bounds);
+
+ PaintAnimatingEdges(canvas, bounds);
+
+ canvas->Restore();
+}
+
+void CompactLocationBarView::Layout() {
+ if (!reload_button_)
+ return; // Not initialized yet, do nothing.
+
+ int cur_x = kCompactLocationLeftMargin;
+
+ // Vertically center all items, basing off the reload button.
+ gfx::Size reload_size = reload_button_->GetPreferredSize();
+ int y = (height() - reload_size.height()) / 2;
+ reload_button_->SetBounds(cur_x, y,
+ reload_size.width(), reload_size.height());
+ cur_x += reload_size.width() + kEntryPadding;
+
+ int location_view_width = width() - cur_x - kCompactLocationRightMargin;
+
+ // The location bar gets the rest of the space in the middle. We assume it has
+ // the same height as the reload button.
+ location_bar_view_->SetBounds(cur_x, y, location_view_width,
+ reload_size.height());
+}
+
+void CompactLocationBarView::Paint(gfx::Canvas* canvas) {
+ // This paints the background behind the reload button all the way across to
+ // the end of the CLB. Without this, everything comes up transparent.
+ gfx::Rect bounds = GetLocalBounds();
+ ThemeProvider* tp = GetThemeProvider();
+ // Now convert from screen to parent coordinates.
+ gfx::Point origin(bounds.origin());
+ BrowserView* browser_view = host()->browser_view();
+ ConvertPointToView(NULL, browser_view, &origin);
+ bounds.set_origin(origin);
+ // Finally, calculate the background image tiling offset.
+ origin = browser_view->OffsetPointForToolbarBackgroundImage(origin);
+
+ canvas->TileImageInt(*tp->GetBitmapNamed(IDR_THEME_TOOLBAR),
+ origin.x(), origin.y(), 0, 0,
+ bounds.width(), bounds.height());
+ View::Paint(canvas);
+}
+
+void CompactLocationBarView::ViewHierarchyChanged(bool is_add,
+ View* parent,
+ View* child) {
+ if (is_add && child == this && !initialized_) {
+ Init();
+ }
+}
+
+void CompactLocationBarView::Focus() {
+ location_bar_view_->SetFocusAndSelection(false);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// views::ButtonListener overrides:
+
+void CompactLocationBarView::ButtonPressed(views::Button* sender,
+ const views::Event& event) {
+ int id = sender->tag();
+ int flags = sender->mouse_event_flags();
+ // Shift-clicking or ctrl-clicking the reload button means we should
+ // ignore any cached content.
+ // TODO(avayvod): eliminate duplication of this logic in
+ // CompactLocationBarView.
+ if (id == IDC_RELOAD && (event.IsShiftDown() || event.IsControlDown())) {
+ id = IDC_RELOAD_IGNORING_CACHE;
+ // Mask off shift/ctrl so they aren't interpreted as affecting the
+ // disposition below.
+ flags &= ~(ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
+ }
+ browser()->ExecuteCommandWithDisposition(
+ id, event_utils::DispositionFromEventFlags(flags));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// AutocompleteEditController overrides:
+
+void CompactLocationBarView::OnAutocompleteAccept(
+ const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url) {
+ browser()->OpenURL(url, GURL(), disposition, transition);
+ clb_host()->StartAutoHideTimer();
+}
+
+void CompactLocationBarView::OnChanged() {
+ // TODO(stevet): Once we put in a location icon, we should resurrect this code
+ // to update the icon.
+ // location_icon_view_->SetImage(
+ // ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ // location_entry_->GetIcon()));
+ // location_icon_view_->ShowTooltip(!location_entry()->IsEditingOrEmpty());
+
+ Layout();
+ SchedulePaint();
+}
+
+void CompactLocationBarView::OnSelectionBoundsChanged() {
+ // TODO(stevet): LocationBarView, for OS_WIN, uses SuggestedTextView here.
+ // We should implement this usage eventually, if appropriate.
+}
+
+void CompactLocationBarView::OnKillFocus() {
+ host()->UnregisterAccelerators();
+}
+
+void CompactLocationBarView::OnSetFocus() {
+ clb_host()->CancelAutoHideTimer();
+ views::FocusManager* focus_manager = GetFocusManager();
+ if (!focus_manager) {
+ NOTREACHED();
+ return;
+ }
+ focus_manager->SetFocusedView(this);
+ host()->RegisterAccelerators();
+}
+
+void CompactLocationBarView::OnInputInProgress(bool in_progress) {
+}
+
+SkBitmap CompactLocationBarView::GetFavicon() const {
+ TabContentsWrapper* wrapper = browser()->GetSelectedTabContentsWrapper();
+ return wrapper ? wrapper->favicon_tab_helper()->GetFavicon() : SkBitmap();
+}
+
+string16 CompactLocationBarView::GetTitle() const {
+ const TabContentsWrapper* wrapper =
+ browser()->GetSelectedTabContentsWrapper();
+ return wrapper ? wrapper->tab_contents()->GetTitle() : string16();
+}
+
+InstantController* CompactLocationBarView::GetInstant() {
+ // TODO(stevet): Re-enable instant for compact nav.
+ // return browser()->instant();
+ return NULL;
+}
+
+TabContentsWrapper* CompactLocationBarView::GetTabContentsWrapper() const {
+ return browser()->GetSelectedTabContentsWrapper();
+}
diff --git a/chrome/browser/ui/views/compact_nav/compact_location_bar_view.h b/chrome/browser/ui/views/compact_nav/compact_location_bar_view.h
new file mode 100644
index 0000000..01c30db
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_location_bar_view.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_LOCATION_BAR_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_LOCATION_BAR_VIEW_H_
+
+#include "base/basictypes.h"
+#include "chrome/browser/autocomplete/autocomplete_edit.h"
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h"
+#include "chrome/browser/ui/views/dropdown_bar_view.h"
+#include "views/controls/button/button.h"
+#include "views/view.h"
+
+class Browser;
+class BrowserView;
+class CompactLocationBarViewHost;
+class LocationBarView;
+class ReloadButton;
+class TabContents;
+
+namespace views {
+class ImageButton;
+class NativeViewHost;
+} // namespace views
+
+// CompactLocationBarView is a version of location bar that is shown under a tab
+// for short period of time when Chrome is in the compact navigation bar mode.
+class CompactLocationBarView : public DropdownBarView,
+ public views::ButtonListener,
+ public AutocompleteEditController {
+ public:
+ explicit CompactLocationBarView(CompactLocationBarViewHost* host);
+ virtual ~CompactLocationBarView();
+
+ // Claims focus for the text field and optionally selects its contents.
+ virtual void SetFocusAndSelection(bool select_all);
+
+ // Update the contained location bar to |contents|.
+ void Update(const TabContents* contents);
+
+ // Overridden from AccessiblePaneView
+ virtual bool SetPaneFocus(int view_storage_id, View* initial_focus) OVERRIDE;
+ virtual void GetAccessibleState(ui::AccessibleViewState* state) OVERRIDE;
+
+ LocationBarView* location_bar_view() { return location_bar_view_; }
+ ReloadButton* reload_button() { return reload_button_; }
+
+ private:
+ Browser* browser() const;
+
+ // Called when the view is added to the tree to initialize the
+ // CompactLocationBarView.
+ void Init();
+
+ // Overridden from views::View.
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void OnPaint(gfx::Canvas* canvas);
+ virtual void Layout() OVERRIDE;
+ virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
+ virtual void ViewHierarchyChanged(bool is_add, views::View* parent,
+ views::View* child) OVERRIDE;
+
+ // No focus border for the location bar, the caret is enough.
+ virtual void Focus();
+ virtual void PaintFocusBorder(gfx::Canvas* canvas) { }
+
+ // Overridden from views::ButtonListener:
+ virtual void ButtonPressed(views::Button* sender,
+ const views::Event& event) OVERRIDE;
+
+ // AutocompleteEditController implementation.
+ virtual void OnAutocompleteAccept(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url) OVERRIDE;
+ virtual void OnChanged() OVERRIDE;
+ virtual void OnSelectionBoundsChanged() OVERRIDE;
+ virtual void OnKillFocus() OVERRIDE;
+ virtual void OnSetFocus() OVERRIDE;
+ virtual SkBitmap GetFavicon() const OVERRIDE;
+ virtual void OnInputInProgress(bool in_progress) OVERRIDE;
+ virtual string16 GetTitle() const OVERRIDE;
+ virtual InstantController* GetInstant() OVERRIDE;
+ virtual TabContentsWrapper* GetTabContentsWrapper() const OVERRIDE;
+
+ CompactLocationBarViewHost* clb_host() {
+ return static_cast<CompactLocationBarViewHost*>(host());
+ }
+
+ ReloadButton* reload_button_;
+ LocationBarView* location_bar_view_;
+ // TODO(stevet): Add the BrowserActionsContainer back.
+
+ // Font used by edit and some of the hints.
+ gfx::Font font_;
+
+ // True if we have already been initialized.
+ bool initialized_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompactLocationBarView);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_LOCATION_BAR_VIEW_H_
diff --git a/chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.cc b/chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.cc
new file mode 100644
index 0000000..7a7a751
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.cc
@@ -0,0 +1,517 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h"
+
+#if defined(TOOLKIT_USES_GTK)
+#include <gtk/gtk.h>
+#endif
+
+#include <algorithm>
+
+#include "base/i18n/rtl.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/browser/ui/view_ids.h"
+#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/tabs/base_tab_strip.h"
+#include "content/browser/renderer_host/render_view_host.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/browser/tab_contents/tab_contents_view.h"
+#include "content/common/notification_source.h"
+#include "ui/base/animation/slide_animation.h"
+#include "ui/base/keycodes/keyboard_codes.h"
+#include "ui/gfx/rect.h"
+#include "views/controls/scrollbar/native_scroll_bar.h"
+#include "views/events/event.h"
+#include "views/focus/external_focus_tracker.h"
+#include "views/focus/view_storage.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+
+namespace {
+
+const int kHideTimeoutInSeconds = 2;
+// TODO(stevet): Share this with CompactLocationBarView. This is the actual
+// height, without the overlap added.
+const int kCompactNavbarSpacerHeight = 4;
+const int kBookmarkBarLocationBarOverlap = 2;
+const int kSpacerLocationbarOverlap = 1;
+
+} // namespace
+
+// An mouse event observer to detect a mouse click on
+// BrowserView's content area and hide the location bar.
+class MouseObserver : public MessageLoopForUI::Observer {
+ public:
+ MouseObserver(CompactLocationBarViewHost* host, BrowserView* view);
+ ~MouseObserver();
+
+ // MessageLoopForUI::Observer overrides.
+#if defined(OS_WIN)
+ virtual void WillProcessMessage(const MSG& native_event) OVERRIDE;
+ virtual void DidProcessMessage(const MSG& native_event) OVERRIDE;
+#elif defined(OS_LINUX)
+ virtual void WillProcessEvent(GdkEvent* native_event) OVERRIDE;
+ virtual void DidProcessEvent(GdkEvent* native_event) OVERRIDE;
+#endif
+
+ void Observe(MessageLoopForUI* loop);
+ void StopObserving(MessageLoopForUI* loop);
+
+ private:
+ // TODO(mad): would be nice to have this on the views::Event class.
+ bool IsMouseEvent(const views::NativeEvent& native_event);
+
+ bool IsSameTopLevelWindow(views::NativeEvent native_event);
+
+ // Tests if the event occurred on the content area, using
+ // root window's coordinates.
+ bool HitContentArea(int x, int y);
+
+ // Tests if |p| in the root window's coordinate is within the |view|'s bound.
+ bool HitOnScreen(const views::View* view, const gfx::Point& p);
+
+ CompactLocationBarViewHost* host_;
+ BrowserView* browser_view_;
+ gfx::NativeView top_level_window_;
+ bool observing_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseObserver);
+};
+
+MouseObserver::MouseObserver(CompactLocationBarViewHost* host,
+ BrowserView* view)
+ : host_(host),
+ browser_view_(view),
+ observing_(false) {
+ top_level_window_ = browser_view_->GetWidget()->GetNativeView();
+}
+
+MouseObserver::~MouseObserver() {
+ StopObserving(MessageLoopForUI::current());
+}
+
+#if defined(OS_WIN)
+void MouseObserver::WillProcessMessage(const MSG& native_event) {}
+void MouseObserver::DidProcessMessage(const MSG& native_event) {
+#elif defined(OS_LINUX)
+void MouseObserver::WillProcessEvent(GdkEvent* native_event) OVERRIDE {}
+void MouseObserver::DidProcessEvent(GdkEvent* native_event) OVERRIDE {
+#endif
+ // Hide the location bar iff the mouse is pressed on the
+ // BrowserView's content area.
+ if (!IsMouseEvent(native_event))
+ return;
+ views::MouseEvent event(native_event);
+ if (event.type() == ui::ET_MOUSE_PRESSED &&
+ IsSameTopLevelWindow(native_event) &&
+ HitContentArea(event.x(), event.y())) {
+ host_->Hide(true);
+ }
+}
+
+void MouseObserver::Observe(MessageLoopForUI* loop) {
+ if (!observing_) {
+ loop->AddObserver(this);
+ observing_ = true;
+ }
+}
+
+void MouseObserver::StopObserving(MessageLoopForUI* loop) {
+ if (observing_) {
+ loop->RemoveObserver(this);
+ observing_ = false;
+ }
+}
+
+bool MouseObserver::IsMouseEvent(const views::NativeEvent& native_event) {
+#if defined(OS_WIN)
+ return views::IsClientMouseEvent(native_event) ||
+ views::IsNonClientMouseEvent(native_event);
+#elif defined(OS_LINUX)
+ return native_event->type == GDK_MOTION_NOTIFY ||
+ native_event->type == GDK_BUTTON_PRESS ||
+ native_event->type == GDK_2BUTTON_PRESS ||
+ native_event->type == GDK_3BUTTON_PRESS ||
+ native_event->type == GDK_BUTTON_RELEASE;
+#endif
+}
+
+// TODO(mad): Would be nice to have a NativeEvent -> NativeWindow mapping.
+// Then, with a GetTopLevel receiving a NativeWindow, we could do this in a
+// platform independent way.
+bool MouseObserver::IsSameTopLevelWindow(views::NativeEvent native_event) {
+#if defined(OS_WIN)
+ return platform_util::GetTopLevel(native_event.hwnd) == top_level_window_;
+#elif defined(OS_LINUX)
+ return gdk_window_get_toplevel(
+ reinterpret_cast<GdkEventAny*>(native_event)->window) ==
+ top_level_window_->window;
+#endif
+}
+
+bool MouseObserver::HitContentArea(int x, int y) {
+ gfx::Point p(x, y);
+ // First, exclude the location bar as it's shown on top of
+ // content area.
+ if (HitOnScreen(host_->view(), p)) {
+ return false;
+ }
+ // Treat the bookmark as a content area when it in detached mode.
+ if (browser_view_->GetBookmarkBarView()->IsDetached() &&
+ browser_view_->IsBookmarkBarVisible() &&
+ HitOnScreen(browser_view_->GetBookmarkBarView(), p)) {
+ return true;
+ }
+ if (HitOnScreen(browser_view_->GetContentsView(), p)) {
+ return true;
+ }
+ return false;
+}
+
+bool MouseObserver::HitOnScreen(const views::View* view, const gfx::Point& p) {
+ gfx::Point origin(0, 0);
+ views::View::ConvertPointToScreen(view, &origin);
+ gfx::Rect new_bounds(origin, view->size());
+ return new_bounds.Contains(p);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarViewHost, public:
+
+CompactLocationBarViewHost::CompactLocationBarViewHost(
+ BrowserView* browser_view) : DropdownBarHost(browser_view),
+ current_tab_model_index_(-1),
+ is_observing_(false) {
+ auto_hide_timer_.reset(new base::OneShotTimer<CompactLocationBarViewHost>());
+ mouse_observer_.reset(new MouseObserver(this, browser_view));
+ CompactLocationBarView* clbv = new CompactLocationBarView(this);
+ Init(clbv, clbv);
+}
+
+CompactLocationBarViewHost::~CompactLocationBarViewHost() {
+ // This may happen if we are destroyed during cleanup.
+ if (browser_view() && browser_view()->browser() &&
+ browser_view()->browser()->tabstrip_model()) {
+ browser_view()->browser()->tabstrip_model()->RemoveObserver(this);
+ }
+}
+
+CompactLocationBarView* CompactLocationBarViewHost::
+ GetCompactLocationBarView() {
+ return static_cast<CompactLocationBarView*>(view());
+}
+
+void CompactLocationBarViewHost::MoveWindowIfNecessary(
+ const gfx::Rect& selection_rect,
+ bool no_redraw) {
+ // We only move the window if one is currently shown. If we don't check
+ // this, then SetWidgetPosition below will end up making the Location Bar
+ // visible.
+ if (!IsVisible())
+ return;
+
+ gfx::Rect new_pos = GetDialogPosition(selection_rect);
+ SetDialogPosition(new_pos, no_redraw);
+
+ // May need to redraw our frame to accommodate bookmark bar styles.
+ view()->SchedulePaint();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// LocationBarView::Delegate implementation:
+TabContentsWrapper* CompactLocationBarViewHost::GetTabContentsWrapper() const {
+ return browser_view()->browser()->GetSelectedTabContentsWrapper();
+}
+
+InstantController* CompactLocationBarViewHost::GetInstant() {
+ // TODO(stevet): Re-enable instant for compact nav.
+ // return browser_view()->browser()->instant();
+ return NULL;
+}
+
+void CompactLocationBarViewHost::OnInputInProgress(bool in_progress) {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarViewHost, views::AcceleratorTarget implementation:
+
+bool CompactLocationBarViewHost::AcceleratorPressed(
+ const views::Accelerator& accelerator) {
+ if (HasFocus()) {
+ DCHECK(view() != NULL);
+ views::FocusManager* focus_manager = view()->GetFocusManager();
+ if (focus_manager)
+ focus_manager->ClearFocus();
+ }
+ Hide(true);
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarViewHost, views::DropdownBarHost implementation:
+
+gfx::Rect CompactLocationBarViewHost::GetDialogPosition(
+ gfx::Rect avoid_overlapping_rect) {
+ if (!browser_view() || !browser_view()->browser() ||
+ !browser_view()->browser()->tabstrip_model()) {
+ return gfx::Rect();
+ }
+ DCHECK_GE(current_tab_model_index_, 0);
+ if (!browser_view()->browser()->tabstrip_model()->ContainsIndex(
+ current_tab_model_index_)) {
+ return gfx::Rect();
+ }
+
+ gfx::Rect new_pos = GetBoundsUnderTab(current_tab_model_index_);
+
+ if (animation_offset() > 0)
+ new_pos.Offset(0, std::min(0, -animation_offset()));
+ return new_pos;
+}
+
+void CompactLocationBarViewHost::SetDialogPosition(const gfx::Rect& new_pos,
+ bool no_redraw) {
+ if (new_pos.IsEmpty())
+ return;
+
+ // Make sure the window edges are clipped to just the visible region. We need
+ // to do this before changing position, so that when we animate the closure
+ // of it it doesn't look like the window crumbles into the toolbar.
+ UpdateWindowEdges(new_pos);
+
+ // TODO(oshima): Animate the window clipping like find-bar.
+ SetWidgetPositionNative(new_pos, no_redraw);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarViewHost, views::TabStripModelObserver implementation:
+
+void CompactLocationBarViewHost::TabClosingAt(TabStripModel* tab_strip_model,
+ TabContentsWrapper* contents,
+ int index) {
+ // TODO(stevet): We need to relocate the compact navigation bar if the
+ // removed tab is not the one we are currently under but the tabstrip does
+ // not have the ideal location yet because the tabs are animating at this
+ // time. Need to investigate the best way to handle this case.
+ Hide(false);
+}
+
+void CompactLocationBarViewHost::TabSelectedAt(TabContentsWrapper* old_contents,
+ TabContentsWrapper* new_contents,
+ int index,
+ bool user_gesture) {
+ current_tab_model_index_ = index;
+ if (new_contents && new_contents->tab_contents()->is_loading()) {
+ Show(false);
+ } else {
+ Hide(false);
+ }
+}
+
+void CompactLocationBarViewHost::TabMoved(TabContentsWrapper* contents,
+ int from_index,
+ int to_index) {
+ if (from_index == current_tab_model_index_) {
+ UpdateOnTabChange(to_index, false);
+ StartAutoHideTimer();
+ }
+}
+
+void CompactLocationBarViewHost::TabChangedAt(TabContentsWrapper* contents,
+ int index,
+ TabChangeType change_type) {
+ if (IsCurrentTabIndex(index) && change_type ==
+ TabStripModelObserver::LOADING_ONLY) {
+ bool was_not_visible = !IsVisible();
+ TabContents* tab_contents = contents->tab_contents();
+ Update(tab_contents, false);
+ if (was_not_visible) {
+ if (tab_contents->is_loading()) {
+ // Register to NavigationController LOAD_STOP so that we can autohide
+ // when loading is done.
+ if (!registrar_.IsRegistered(this, NotificationType::LOAD_STOP,
+ Source<NavigationController>(&tab_contents->controller()))) {
+ registrar_.Add(this, NotificationType::LOAD_STOP,
+ Source<NavigationController>(&tab_contents->controller()));
+ }
+ } else {
+ StartAutoHideTimer();
+ }
+ }
+ }
+}
+
+void CompactLocationBarViewHost::ActiveTabClicked(int index) {
+ UpdateOnTabChange(index, true);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarViewHost, NotificationObserver implementation:
+
+void CompactLocationBarViewHost::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type.value) {
+ case NotificationType::LOAD_STOP: {
+ StartAutoHideTimer();
+ // This is one shot deal...
+ registrar_.Remove(this, NotificationType::LOAD_STOP, source);
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarViewHost public:
+
+gfx::Rect CompactLocationBarViewHost::GetBoundsUnderTab(int model_index) const {
+ DCHECK(!browser_view()->UseVerticalTabs());
+
+ // Get the position of the left-bottom corner of the tab on the
+ // widget. The widget of the tab is same as the widget of the
+ // BrowserView which is the parent of the host.
+ BaseTabStrip* tabstrip =
+ static_cast<BaseTabStrip*>(browser_view()->tabstrip());
+ gfx::Rect tab_bounds =
+ tabstrip->ideal_bounds(tabstrip->ModelIndexToTabIndex(model_index));
+ gfx::Rect navbar_bounds(gfx::Point(tab_bounds.x(), tab_bounds.height()),
+ view()->GetPreferredSize());
+
+ // Convert our point to be relative to the widget, since the native code that
+ // draws the dropdown is not in the BrowserView coordinate system.
+ gfx::Point origin = navbar_bounds.origin();
+ views::View::ConvertPointToWidget(browser_view(), &origin);
+ navbar_bounds.set_origin(origin);
+
+ // For RTL case x() defines tab right corner.
+ if (base::i18n::IsRTL())
+ navbar_bounds.Offset(tab_bounds.width(), 0);
+ navbar_bounds.Offset(tabstrip->x(), tabstrip->y());
+
+ // The compact location bar must be smaller than browser_width.
+ int width = std::min(browser_view()->width(),
+ view()->GetPreferredSize().width());
+
+ // Try to center around the tab.
+ navbar_bounds.set_x(browser_view()->GetMirroredXInView(
+ navbar_bounds.x()) - ((width - tab_bounds.width()) / 2));
+
+ // Adjust the location to create the illusion that the compact location bar
+ // is a part of the spacer or bookmark bar, depending on which is showing.
+ if (browser_view()->IsBookmarkBarVisible() &&
+ !browser_view()->GetBookmarkBarView()->IsDetached()) {
+ // TODO(stevet): Compact location bar does not have right background image
+ // yet, so kBookmarkBarLocationBarOverlap is tentative. Fix this once UI is
+ // settled. This may be entirely replaced by a popup CLB, anyway.
+ navbar_bounds.Offset(0,
+ browser_view()->GetBookmarkBarView()->bounds().height() +
+ kCompactNavbarSpacerHeight - kBookmarkBarLocationBarOverlap);
+ } else {
+ // TODO(stevet): kSpacerLocationbarOverlap is tentative as well, as above.
+ navbar_bounds.Offset(0, kCompactNavbarSpacerHeight -
+ kSpacerLocationbarOverlap);
+ }
+
+ // TODO(stevet): Adjust to the right if there is an info bar visible.
+ return navbar_bounds.AdjustToFit(browser_view()->bounds());
+}
+
+void CompactLocationBarViewHost::Update(TabContents* contents, bool animate) {
+ // Don't animate if the bar is already shown.
+ bool showing_in_same_tab = animation()->IsShowing() && IsCurrentTab(contents);
+ current_tab_model_index_ = browser_view()->browser()->active_index();
+ Hide(false);
+ GetCompactLocationBarView()->Update(contents);
+ Show(animate && !showing_in_same_tab);
+ // If the tab is loading, we must wait for the notification that it is done.
+ if (contents && !contents->is_loading()) {
+ // This will be a NOOP if we have focus.
+ // We never want to stay up, unless we have focus.
+ StartAutoHideTimer();
+ }
+}
+
+void CompactLocationBarViewHost::UpdateOnTabChange(int model_index,
+ bool animate) {
+ DCHECK_GE(model_index, 0);
+ if (IsCurrentTabIndex(model_index) && animation()->IsShowing()) {
+ return;
+ }
+ current_tab_model_index_ = model_index;
+ Update(browser_view()->browser()->tabstrip_model()->
+ GetTabContentsAt(model_index)->tab_contents(), animate);
+}
+
+void CompactLocationBarViewHost::StartAutoHideTimer() {
+ if (!IsVisible() || HasFocus())
+ return;
+
+ if (auto_hide_timer_->IsRunning()) {
+ // Restart the timer.
+ auto_hide_timer_->Reset();
+ } else {
+ auto_hide_timer_->Start(base::TimeDelta::FromSeconds(kHideTimeoutInSeconds),
+ this, &CompactLocationBarViewHost::HideCallback);
+ }
+}
+
+void CompactLocationBarViewHost::CancelAutoHideTimer() {
+ auto_hide_timer_->Stop();
+}
+
+void CompactLocationBarViewHost::SetEnabled(bool enabled) {
+ if (enabled && !is_observing_) {
+ browser_view()->browser()->tabstrip_model()->AddObserver(this);
+ is_observing_ = true;
+ } else {
+ browser_view()->browser()->tabstrip_model()->RemoveObserver(this);
+ is_observing_ = false;
+ }
+}
+
+void CompactLocationBarViewHost::Show(bool animate) {
+ CancelAutoHideTimer();
+ mouse_observer_->Observe(MessageLoopForUI::current());
+ DropdownBarHost::Show(animate);
+ host()->Show();
+}
+
+void CompactLocationBarViewHost::Hide(bool animate) {
+ CancelAutoHideTimer();
+ mouse_observer_->StopObserving(MessageLoopForUI::current());
+ host()->Hide();
+ DropdownBarHost::Hide(animate);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactLocationBarViewHost private:
+bool CompactLocationBarViewHost::HasFocus() {
+ DCHECK(view() != NULL);
+ views::FocusManager* focus_manager = view()->GetFocusManager();
+ return focus_manager && view()->Contains(focus_manager->GetFocusedView());
+}
+
+void CompactLocationBarViewHost::HideCallback() {
+ if (IsVisible() && !HasFocus())
+ Hide(true);
+}
+
+bool CompactLocationBarViewHost::IsCurrentTabIndex(int index) {
+ return current_tab_model_index_ == index;
+}
+
+bool CompactLocationBarViewHost::IsCurrentTab(TabContents* contents) {
+ TabStripModel* tab_strip_model = browser_view()->browser()->tabstrip_model();
+ return tab_strip_model->ContainsIndex(current_tab_model_index_) &&
+ tab_strip_model->GetTabContentsAt(current_tab_model_index_)->
+ tab_contents() == contents;
+}
diff --git a/chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h b/chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h
new file mode 100644
index 0000000..1037853
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h
@@ -0,0 +1,138 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_LOCATION_BAR_VIEW_HOST_H_
+#define CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_LOCATION_BAR_VIEW_HOST_H_
+
+#include "base/timer.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/views/location_bar/location_bar_view.h"
+
+class BrowserView;
+class CompactLocationBarView;
+class DropdownBarHost;
+class MouseObserver;
+class NotificationObserver;
+class NotificationRegistrar;
+class TabContents;
+
+namespace gfx {
+class Rect;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// The CompactLocationBarViewHost implements the container window for the
+// floating location bar.
+//
+// There is one CompactLocationBarViewHost per BrowserView, and its state
+// is updated whenever the selected Tab is changed. The
+// CompactLocationBarViewHost is created when the BrowserView is attached
+// to the frame's Widget for the first time, and enabled/disabled
+// when the compact navigation bar is toggled.
+//
+////////////////////////////////////////////////////////////////////////////////
+class CompactLocationBarViewHost : public DropdownBarHost,
+ public TabStripModelObserver,
+ public NotificationObserver,
+ public LocationBarView::Delegate {
+ public:
+ explicit CompactLocationBarViewHost(BrowserView* browser_view);
+ virtual ~CompactLocationBarViewHost();
+
+ // Returns the bounds to locate the compact location bar under the tab. The
+ // coordinate system is the browser frame for Windows, otherwise the browser
+ // view.
+ gfx::Rect GetBoundsUnderTab(int model_index) const;
+
+ // Updates the content and the position of the compact location bar.
+ // |model_index| is the index of the tab the compact location bar
+ // will be attached to and |animate| specifies if the location bar
+ // should animate when shown. The second version gets the actual |contents|
+ // instead of the |model_index|.
+ void UpdateOnTabChange(int model_index, bool animate);
+ void Update(TabContents* contents, bool animate);
+
+ // (Re)Starts the popup timer that hides the popup after X seconds.
+ void StartAutoHideTimer();
+
+ // Cancels the popup timer.
+ void CancelAutoHideTimer();
+
+ // Enable/disable the compact location bar.
+ void SetEnabled(bool enabled);
+
+ CompactLocationBarView* GetCompactLocationBarView();
+
+ // Readjust the position of the host window while avoiding |selection_rect|.
+ // |selection_rect| is expected to have coordinates relative to the top of
+ // the web page area. If |no_redraw| is true, the window will be moved without
+ // redrawing siblings.
+ virtual void MoveWindowIfNecessary(const gfx::Rect& selection_rect,
+ bool no_redraw);
+
+ // Overridden from DropdownBarhost.
+ virtual void Show(bool animate) OVERRIDE;
+ virtual void Hide(bool animate) OVERRIDE;
+ virtual gfx::Rect GetDialogPosition(
+ gfx::Rect avoid_overlapping_rect) OVERRIDE;
+ virtual void SetDialogPosition(const gfx::Rect& new_pos,
+ bool no_redraw) OVERRIDE;
+
+ // Overridden from views::AcceleratorTarget in DropdownBarHost class.
+ virtual bool AcceleratorPressed(
+ const views::Accelerator& accelerator) OVERRIDE;
+
+ // Overridden from TabStripModelObserver class.
+ virtual void TabClosingAt(TabStripModel* tab_strip_model,
+ TabContentsWrapper* contents,
+ int index) OVERRIDE;
+ virtual void TabSelectedAt(TabContentsWrapper* old_contents,
+ TabContentsWrapper* new_contents,
+ int index,
+ bool user_gesture) OVERRIDE;
+ virtual void TabMoved(TabContentsWrapper* contents,
+ int from_index,
+ int to_index) OVERRIDE;
+ virtual void TabChangedAt(TabContentsWrapper* contents, int index,
+ TabChangeType change_type) OVERRIDE;
+ virtual void ActiveTabClicked(int index) OVERRIDE;
+
+ // Overridden from NotificationObserver.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE;
+
+ // LocationBarView::Delegate overrides
+ virtual TabContentsWrapper* GetTabContentsWrapper() const OVERRIDE;
+ virtual InstantController* GetInstant() OVERRIDE;
+ virtual void OnInputInProgress(bool in_progress) OVERRIDE;
+
+ private:
+ friend class MouseObserver;
+ friend class CompactLocationBarViewHostTest;
+
+ bool HasFocus();
+ void HideCallback();
+ bool IsCurrentTabIndex(int index);
+ bool IsCurrentTab(TabContents* contents);
+
+ // We use this to be notified of the end of a page load so we can hide.
+ NotificationRegistrar registrar_;
+
+ // The index of the tab, in terms of the model, that the compact location bar
+ // is attached to.
+ int current_tab_model_index_;
+
+ scoped_ptr<base::OneShotTimer<CompactLocationBarViewHost> > auto_hide_timer_;
+
+ scoped_ptr<MouseObserver> mouse_observer_;
+
+ // Track if we are currently observing the tabstrip model.
+ bool is_observing_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompactLocationBarViewHost);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_LOCATION_BAR_VIEW_HOST_H_
diff --git a/chrome/browser/ui/views/compact_nav/compact_navigation_bar.cc b/chrome/browser/ui/views/compact_nav/compact_navigation_bar.cc
new file mode 100644
index 0000000..64e3592
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_navigation_bar.cc
@@ -0,0 +1,186 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/compact_nav/compact_navigation_bar.h"
+
+#include "base/logging.h"
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/toolbar/back_forward_menu_model.h"
+#include "chrome/browser/ui/view_ids.h"
+#include "chrome/browser/ui/views/event_utils.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/theme_background.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "grit/theme_resources_standard.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/theme_provider.h"
+#include "ui/gfx/canvas.h"
+#include "views/controls/button/button_dropdown.h"
+#include "views/controls/button/image_button.h"
+#include "views/controls/image_view.h"
+#include "views/controls/native/native_view_host.h"
+
+// Padding inside each button around the image.
+static const int kInnerPadding = 1;
+
+// Spacing between buttons (excluding left/right most margin)
+static const int kHorizMargin = 3;
+
+// Left side margin of the back button to align with the main menu.
+static const int kBackButtonLeftMargin = 10;
+
+// Right side margin of the forward button to align with the main menu.
+static const int kForwardButtonRightMargin = 1;
+
+// Preferred height.
+static const int kPreferredHeight = 25;
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactNavigationBar public:
+
+CompactNavigationBar::CompactNavigationBar(BrowserView* browser_view)
+ : browser_view_(browser_view),
+ initialized_(false),
+ back_(NULL),
+ bf_separator_(NULL),
+ forward_(NULL) {
+ Browser* browser = browser_view_->browser();
+ browser->command_updater()->AddCommandObserver(IDC_BACK, this);
+ browser->command_updater()->AddCommandObserver(IDC_FORWARD, this);
+}
+
+CompactNavigationBar::~CompactNavigationBar() {
+ Browser* browser = browser_view_->browser();
+ browser->command_updater()->RemoveCommandObserver(IDC_BACK, this);
+ browser->command_updater()->RemoveCommandObserver(IDC_FORWARD, this);
+}
+
+void CompactNavigationBar::Init() {
+ DCHECK(!initialized_);
+
+ Browser* browser = browser_view_->browser();
+
+ back_menu_model_.reset(new BackForwardMenuModel(
+ browser, BackForwardMenuModel::BACKWARD_MENU));
+ forward_menu_model_.reset(new BackForwardMenuModel(
+ browser, BackForwardMenuModel::FORWARD_MENU));
+
+ ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance();
+
+ back_ = new views::ButtonDropDown(this, back_menu_model_.get());
+ back_->set_triggerable_event_flags(ui::EF_LEFT_BUTTON_DOWN |
+ ui::EF_MIDDLE_BUTTON_DOWN);
+ back_->set_tag(IDC_BACK);
+ back_->SetTooltipText(
+ UTF16ToWide(l10n_util::GetStringUTF16(IDS_TOOLTIP_BACK)));
+ back_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_BACK));
+ back_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
+ views::ImageButton::ALIGN_MIDDLE);
+ AddChildView(back_);
+
+ bf_separator_ = new views::ImageView;
+ bf_separator_->SetImage(
+ resource_bundle.GetBitmapNamed(IDR_COMPACTNAV_SEPARATOR));
+ AddChildView(bf_separator_);
+
+ forward_ = new views::ButtonDropDown(this, forward_menu_model_.get());
+ forward_->set_triggerable_event_flags(ui::EF_LEFT_BUTTON_DOWN |
+ ui::EF_MIDDLE_BUTTON_DOWN);
+ forward_->set_tag(IDC_FORWARD);
+ forward_->SetTooltipText(
+ UTF16ToWide(l10n_util::GetStringUTF16(IDS_TOOLTIP_FORWARD)));
+ forward_->SetAccessibleName(l10n_util::GetStringUTF16((IDS_ACCNAME_FORWARD)));
+ forward_->SetImageAlignment(views::ImageButton::ALIGN_CENTER,
+ views::ImageButton::ALIGN_MIDDLE);
+ AddChildView(forward_);
+
+ LoadImages();
+
+ initialized_ = true;
+}
+
+gfx::Size CompactNavigationBar::GetPreferredSize() {
+ int width = kBackButtonLeftMargin;
+ width += back_->GetPreferredSize().width() + kInnerPadding * 2;
+ width += kHorizMargin;
+ width += bf_separator_->GetPreferredSize().width();
+ width += kHorizMargin;
+ width += forward_->GetPreferredSize().width() + kInnerPadding * 2;
+ width += kForwardButtonRightMargin;
+ return gfx::Size(width, kPreferredHeight);
+}
+
+void CompactNavigationBar::Layout() {
+ if (!initialized_)
+ return;
+
+ // Layout forward/back buttons after entry views as follows:
+ // [Back]|[Forward]
+ int curx = kBackButtonLeftMargin;
+ // "Back | Forward" section.
+ gfx::Size button_size = back_->GetPreferredSize();
+ button_size.set_width(button_size.width() + kInnerPadding * 2);
+ back_->SetBounds(curx, 0, button_size.width(), height());
+ curx += button_size.width() + kHorizMargin;
+
+ button_size = bf_separator_->GetPreferredSize();
+ bf_separator_->SetBounds(curx, 0, button_size.width(), height());
+ curx += button_size.width() + kHorizMargin;
+
+ button_size = forward_->GetPreferredSize();
+ button_size.set_width(button_size.width() + kInnerPadding * 2);
+ forward_->SetBounds(curx, 0, button_size.width(), height());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// views::ButtonListener implementation.
+
+void CompactNavigationBar::ButtonPressed(
+ views::Button* sender, const views::Event& event) {
+ browser_view_->browser()->ExecuteCommandWithDisposition(
+ sender->tag(),
+ event_utils::DispositionFromEventFlags(sender->mouse_event_flags()));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CommandUpdater::CommandObserver implementation.
+void CompactNavigationBar::EnabledStateChangedForCommand(int id, bool enabled) {
+ switch (id) {
+ case IDC_BACK:
+ back_->SetEnabled(enabled);
+ break;
+ case IDC_FORWARD:
+ forward_->SetEnabled(enabled);
+ break;
+ }
+}
+
+void CompactNavigationBar::LoadImages() {
+ ui::ThemeProvider* tp = GetThemeProvider();
+
+ // TODO(stevet): Hook up other button image resources like
+ // IDR_COMPACTNAV_FORWARD for the different button states.
+ back_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_BACK));
+ back_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_BACK_H));
+ back_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_BACK_P));
+ back_->SetImage(views::CustomButton::BS_DISABLED,
+ tp->GetBitmapNamed(IDR_BACK_D));
+
+ forward_->SetImage(views::CustomButton::BS_NORMAL,
+ tp->GetBitmapNamed(IDR_FORWARD));
+ forward_->SetImage(views::CustomButton::BS_HOT,
+ tp->GetBitmapNamed(IDR_FORWARD_H));
+ forward_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_FORWARD_P));
+ forward_->SetImage(views::CustomButton::BS_DISABLED,
+ tp->GetBitmapNamed(IDR_FORWARD_D));
+}
diff --git a/chrome/browser/ui/views/compact_nav/compact_navigation_bar.h b/chrome/browser/ui/views/compact_nav/compact_navigation_bar.h
new file mode 100644
index 0000000..3e33098
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_navigation_bar.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_NAVIGATION_BAR_H_
+#define CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_NAVIGATION_BAR_H_
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/command_updater.h"
+#include "views/controls/button/button.h"
+#include "views/view.h"
+
+class BackForwardMenuModel;
+class BrowserView;
+
+namespace views {
+class ImageButton;
+class ImageView;
+}
+
+// This class provides a small navigation bar that includes back, forward, and
+// a small text entry box.
+class CompactNavigationBar : public views::View,
+ public views::ButtonListener,
+ public CommandUpdater::CommandObserver {
+ public:
+ explicit CompactNavigationBar(BrowserView* browser_view);
+ virtual ~CompactNavigationBar();
+
+ // Must be called before anything else, but after adding this view to the
+ // widget.
+ void Init();
+
+ // views::View overrides.
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void Layout() OVERRIDE;
+
+ private:
+ // views::ButtonListener implementation.
+ virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+
+ // CommandUpdater::CommandObserver implementation.
+ virtual void EnabledStateChangedForCommand(int id, bool enabled);
+
+ // Load the images for the back and forward buttons.
+ void LoadImages();
+
+ BrowserView* browser_view_;
+
+ bool initialized_;
+
+ views::ImageButton* back_;
+ views::ImageView* bf_separator_;
+ views::ImageButton* forward_;
+
+ // History menu for back and forward buttons.
+ scoped_ptr<BackForwardMenuModel> back_menu_model_;
+ scoped_ptr<BackForwardMenuModel> forward_menu_model_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompactNavigationBar);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_NAVIGATION_BAR_H_
diff --git a/chrome/browser/ui/views/compact_nav/compact_options_bar.cc b/chrome/browser/ui/views/compact_nav/compact_options_bar.cc
new file mode 100644
index 0000000..677485f
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_options_bar.cc
@@ -0,0 +1,151 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/compact_nav/compact_options_bar.h"
+
+#include "chrome/app/chrome_command_ids.h"
+#include "chrome/browser/ui/toolbar/wrench_menu_model.h"
+#include "chrome/browser/ui/view_ids.h"
+#include "chrome/browser/ui/views/event_utils.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/toolbar_view.h"
+#include "chrome/browser/ui/views/wrench_menu.h"
+#include "grit/chromium_strings.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/canvas.h"
+#include "views/controls/button/menu_button.h"
+
+namespace {
+const int kPreferredHeight = 25;
+// Pad the left and right ends from other tabstrip region items.
+const int kEndPadding = 3;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactOptionsBar public:
+
+CompactOptionsBar::CompactOptionsBar(BrowserView* browser_view)
+ : browser_view_(browser_view),
+ initialized_(false),
+ app_menu_(NULL) {
+}
+
+CompactOptionsBar::~CompactOptionsBar() {
+}
+
+void CompactOptionsBar::Init() {
+ DCHECK(!initialized_);
+ initialized_ = true;
+
+ wrench_menu_model_.reset(new WrenchMenuModel(this, browser_view_->browser()));
+
+ app_menu_ = new views::MenuButton(NULL, std::wstring(), this, false);
+ app_menu_->set_border(NULL);
+ app_menu_->EnableCanvasFlippingForRTLUI(true);
+ app_menu_->SetAccessibleName(l10n_util::GetStringUTF16(IDS_ACCNAME_APP));
+ app_menu_->SetTooltipText(UTF16ToWide(l10n_util::GetStringFUTF16(
+ IDS_APPMENU_TOOLTIP,
+ l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))));
+ app_menu_->SetID(VIEW_ID_APP_MENU);
+ AddChildView(app_menu_);
+
+ LoadImages();
+}
+
+void CompactOptionsBar::AddMenuListener(views::MenuListener* listener) {
+ menu_listeners_.push_back(listener);
+}
+
+void CompactOptionsBar::RemoveMenuListener(views::MenuListener* listener) {
+ for (std::vector<views::MenuListener*>::iterator i(menu_listeners_.begin());
+ i != menu_listeners_.end(); ++i) {
+ if (*i == listener) {
+ menu_listeners_.erase(i);
+ return;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactOptionsBar, views::View overrides:
+
+gfx::Size CompactOptionsBar::GetPreferredSize() {
+ int width = kEndPadding * 2 + app_menu_->GetPreferredSize().width();
+ // TODO(stevet): Add the width of the browser actions container here when that
+ // is added to the bar.
+ return gfx::Size(width, kPreferredHeight);
+}
+
+void CompactOptionsBar::Layout() {
+ if (!initialized_)
+ return;
+
+ gfx::Size button_size = app_menu_->GetPreferredSize();
+ app_menu_->SetBounds(kEndPadding, 0, button_size.width(), height());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactOptionsBar, views::MenuDelegate implementation:
+
+void CompactOptionsBar::RunMenu(views::View* source,
+ const gfx::Point& /* pt */) {
+ DCHECK_EQ(VIEW_ID_APP_MENU, source->GetID());
+
+ wrench_menu_ = new WrenchMenu(browser_view_->browser());
+ wrench_menu_->Init(wrench_menu_model_.get());
+
+ for (size_t i = 0; i < menu_listeners_.size(); ++i)
+ menu_listeners_[i]->OnMenuOpened();
+
+ // Note that this might be destroyed while the menu is running.
+ wrench_menu_->RunMenu(app_menu_);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactOptionsBar, ui::AcceleratorProvider implementation:
+
+bool CompactOptionsBar::GetAcceleratorForCommandId(int command_id,
+ ui::Accelerator* accelerator) {
+ // TODO(stevet): Can we share ToolbarView's implementation? It's exactly the
+ // same so far.
+ // The standard Ctrl-X, Ctrl-V and Ctrl-C are not defined as accelerators
+ // anywhere so we need to check for them explicitly here.
+ // TODO(cpu) Bug 1109102. Query WebKit land for the actual bindings.
+ switch (command_id) {
+ case IDC_CUT:
+ *accelerator = views::Accelerator(ui::VKEY_X, false, true, false);
+ return true;
+ case IDC_COPY:
+ *accelerator = views::Accelerator(ui::VKEY_C, false, true, false);
+ return true;
+ case IDC_PASTE:
+ *accelerator = views::Accelerator(ui::VKEY_V, false, true, false);
+ return true;
+ }
+ // Else, we retrieve the accelerator information from the frame.
+ return GetWidget()->GetAccelerator(command_id, accelerator);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CompactOptionsBar, views::ButtonListener implementation.
+
+void CompactOptionsBar::ButtonPressed(views::Button* sender,
+ const views::Event& event) {
+ browser_view_->browser()->ExecuteCommandWithDisposition(
+ sender->tag(),
+ event_utils::DispositionFromEventFlags(sender->mouse_event_flags()));
+}
+
+void CompactOptionsBar::LoadImages() {
+ // Reuse the resources loaded for the Toolbar's AppMenu.
+ DCHECK(browser_view_->toolbar());
+ app_menu_->SetIcon(browser_view_->toolbar()->GetAppMenuIcon(
+ views::CustomButton::BS_NORMAL));
+ app_menu_->SetHoverIcon(browser_view_->toolbar()->GetAppMenuIcon(
+ views::CustomButton::BS_HOT));
+ app_menu_->SetPushedIcon(browser_view_->toolbar()->GetAppMenuIcon(
+ views::CustomButton::BS_PUSHED));
+}
diff --git a/chrome/browser/ui/views/compact_nav/compact_options_bar.h b/chrome/browser/ui/views/compact_nav/compact_options_bar.h
new file mode 100644
index 0000000..0d8cd20e6
--- /dev/null
+++ b/chrome/browser/ui/views/compact_nav/compact_options_bar.h
@@ -0,0 +1,81 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_OPTIONS_BAR_H_
+#define CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_OPTIONS_BAR_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/command_updater.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "views/controls/button/button.h"
+#include "views/controls/menu/view_menu_delegate.h"
+#include "views/view.h"
+
+class BrowserView;
+class WrenchMenu;
+
+namespace views {
+class MenuButton;
+class MenuListener;
+} // namespace views
+
+// This class provides a small options bar that includes browser actions and
+// the wrench menu button.
+class CompactOptionsBar : public views::View,
+ public views::ViewMenuDelegate,
+ public ui::AcceleratorProvider,
+ public views::ButtonListener {
+ public:
+ explicit CompactOptionsBar(BrowserView* browser_view);
+ virtual ~CompactOptionsBar();
+
+ // Must be called before anything else, but after adding this view to the
+ // widget.
+ void Init();
+
+ // Add a listener to receive a callback when the menu opens.
+ void AddMenuListener(views::MenuListener* listener);
+
+ // Remove a menu listener.
+ void RemoveMenuListener(views::MenuListener* listener);
+
+ // Overridden from views::View.
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
+ virtual void Layout() OVERRIDE;
+
+ // Overridden from views::MenuDelegate:
+ virtual void RunMenu(views::View* source, const gfx::Point& pt) OVERRIDE;
+
+ // Overridden from ui::AcceleratorProvider:
+ virtual bool GetAcceleratorForCommandId(
+ int command_id,
+ ui::Accelerator* accelerator) OVERRIDE;
+
+ private:
+ // views::ButtonListener implementation.
+ virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+
+ // Load the images for the back and forward buttons.
+ void LoadImages();
+
+ BrowserView* browser_view_;
+
+ bool initialized_;
+
+ // Button and models for the wrench/app menu.
+ views::MenuButton* app_menu_;
+ scoped_ptr<ui::SimpleMenuModel> wrench_menu_model_;
+ scoped_refptr<WrenchMenu> wrench_menu_;
+ std::vector<views::MenuListener*> menu_listeners_;
+
+ // TODO(stevet): Add the BrowserActionsContainer.
+
+ DISALLOW_COPY_AND_ASSIGN(CompactOptionsBar);
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_COMPACT_NAV_COMPACT_OPTIONS_BAR_H_
diff --git a/chrome/browser/ui/views/dropdown_bar_host.cc b/chrome/browser/ui/views/dropdown_bar_host.cc
index 875e8a4..9675589 100644
--- a/chrome/browser/ui/views/dropdown_bar_host.cc
+++ b/chrome/browser/ui/views/dropdown_bar_host.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "chrome/browser/ui/view_ids.h"
+#include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
#include "chrome/browser/ui/views/dropdown_bar_view.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "ui/base/animation/slide_animation.h"
@@ -44,14 +45,20 @@ bool DropdownBarHost::disable_animations_during_testing_ = false;
DropdownBarHost::DropdownBarHost(BrowserView* browser_view)
: browser_view_(browser_view),
view_(NULL),
+ delegate_(NULL),
animation_offset_(0),
focus_manager_(NULL),
esc_accel_target_registered_(false),
is_visible_(false) {
}
-void DropdownBarHost::Init(DropdownBarView* view) {
+void DropdownBarHost::Init(views::View* view,
+ DropdownBarHostDelegate* delegate) {
+ DCHECK(view);
+ DCHECK(delegate);
+
view_ = view;
+ delegate_ = delegate;
// Initialize the host.
host_.reset(views::Widget::CreateWidget());
@@ -102,7 +109,7 @@ void DropdownBarHost::Show(bool animate) {
}
void DropdownBarHost::SetFocusAndSelection() {
- view_->SetFocusAndSelection(true);
+ delegate_->SetFocusAndSelection(true);
}
bool DropdownBarHost::IsAnimating() const {
@@ -112,13 +119,23 @@ bool DropdownBarHost::IsAnimating() const {
void DropdownBarHost::Hide(bool animate) {
if (!IsVisible())
return;
- if (animate && !disable_animations_during_testing_) {
- animation_->Reset(1.0);
+ if (animate && !disable_animations_during_testing_ &&
+ !animation_->IsClosing()) {
animation_->Hide();
} else {
- StopAnimation();
- is_visible_ = false;
- host_->Hide();
+ if (animation_->IsClosing()) {
+ // If we're in the middle of a close animation, skip immediately to the
+ // end of the animation.
+ StopAnimation();
+ } else {
+ // Otherwise we need to set both the animation state to ended and the
+ // DropdownBarHost state to ended/hidden, otherwise the next time we try
+ // to show the bar, it might refuse to do so. Note that we call
+ // AnimationEnded ourselves as Reset does not call it if we are not
+ // animating here.
+ animation_->Reset();
+ AnimationEnded(animation_.get());
+ }
}
}
@@ -171,7 +188,7 @@ void DropdownBarHost::AnimationProgressed(const ui::Animation* animation) {
// Let the view know if we are animating, and at which offset to draw the
// edges.
- view_->set_animation_offset(animation_offset_);
+ delegate_->SetAnimationOffset(animation_offset_);
view_->SchedulePaint();
}
diff --git a/chrome/browser/ui/views/dropdown_bar_host.h b/chrome/browser/ui/views/dropdown_bar_host.h
index c53f40c..914f240d 100644
--- a/chrome/browser/ui/views/dropdown_bar_host.h
+++ b/chrome/browser/ui/views/dropdown_bar_host.h
@@ -15,18 +15,19 @@
#include "views/focus/focus_manager.h"
class BrowserView;
+class DropdownBarHostDelegate;
class DropdownBarView;
class TabContents;
namespace ui {
class SlideAnimation;
-}
+} // namespace ui
namespace views {
class ExternalFocusTracker;
class View;
class Widget;
-}
+} // namespace views
////////////////////////////////////////////////////////////////////////////////
//
@@ -45,8 +46,7 @@ class DropdownBarHost : public views::AcceleratorTarget,
explicit DropdownBarHost(BrowserView* browser_view);
virtual ~DropdownBarHost();
- // Initializes the dropdown bar host with the give view.
- void Init(DropdownBarView* view);
+ void Init(views::View* view, DropdownBarHostDelegate* delegate);
// Whether we are animating the position of the dropdown widget.
bool IsAnimating() const;
@@ -101,7 +101,7 @@ class DropdownBarHost : public views::AcceleratorTarget,
protected:
// Returns the dropdown bar view.
- DropdownBarView* view() const { return view_; }
+ views::View* view() const { return view_; }
// Returns the focus tracker.
views::ExternalFocusTracker* focus_tracker() const {
@@ -154,7 +154,8 @@ class DropdownBarHost : public views::AcceleratorTarget,
BrowserView* browser_view_;
// Our view, which is responsible for drawing the UI.
- DropdownBarView* view_;
+ views::View* view_;
+ DropdownBarHostDelegate* delegate_;
// The y position pixel offset of the widget while animating the
// dropdown widget.
diff --git a/chrome/browser/ui/views/dropdown_bar_host_delegate.h b/chrome/browser/ui/views/dropdown_bar_host_delegate.h
new file mode 100644
index 0000000..9b98b4b
--- /dev/null
+++ b/chrome/browser/ui/views/dropdown_bar_host_delegate.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_VIEWS_DROPDOWN_BAR_HOST_DELEGATE_H_
+#define CHROME_BROWSER_UI_VIEWS_DROPDOWN_BAR_HOST_DELEGATE_H_
+
+class DropdownBarHostDelegate {
+ public:
+ // Claims focus for the text field and selects its contents.
+ virtual void SetFocusAndSelection(bool select_all) = 0;
+
+ // Updates the view to let it know where the host is clipping the
+ // dropdown widget (while animating the opening or closing of the widget).
+ virtual void SetAnimationOffset(int offset) = 0;
+
+ protected:
+ virtual ~DropdownBarHostDelegate() {}
+};
+
+#endif // CHROME_BROWSER_UI_VIEWS_DROPDOWN_BAR_HOST_DELEGATE_H_
diff --git a/chrome/browser/ui/views/dropdown_bar_view.cc b/chrome/browser/ui/views/dropdown_bar_view.cc
new file mode 100644
index 0000000..e1a58eb
--- /dev/null
+++ b/chrome/browser/ui/views/dropdown_bar_view.cc
@@ -0,0 +1,107 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/dropdown_bar_view.h"
+
+#include "chrome/browser/themes/theme_service.h"
+#include "chrome/browser/ui/view_ids.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources_standard.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/canvas.h"
+#include "views/background.h"
+#include "views/widget/widget.h"
+
+namespace {
+
+// When we are animating, we draw only the top part of the left and right
+// edges to give the illusion that the find dialog is attached to the
+// window during this animation; this is the height of the items we draw.
+const int kAnimatingEdgeHeight = 5;
+
+} // namespace
+
+DropdownBarView::DropdownBarView(DropdownBarHost* host)
+ : host_(host),
+ animation_offset_(0),
+ dialog_left_(NULL),
+ dialog_middle_(NULL),
+ dialog_right_(NULL) {
+}
+
+DropdownBarView::~DropdownBarView() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DropDownBarView, public:
+
+void DropdownBarView::SetAnimationOffset(int offset) {
+ animation_offset_ = offset;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DropDownBarView, protected:
+
+void DropdownBarView::SetDialogBorderBitmaps(const SkBitmap* dialog_left,
+ const SkBitmap* dialog_middle,
+ const SkBitmap* dialog_right) {
+ dialog_left_ = dialog_left;
+ dialog_middle_ = dialog_middle;
+ dialog_right_ = dialog_right;
+}
+
+gfx::Rect DropdownBarView::PaintOffsetToolbarBackground(gfx::Canvas* canvas) {
+ // Determine the find bar size as well as the offset from which to tile the
+ // toolbar background image. First, get the widget bounds.
+ gfx::Rect bounds = GetWidget()->GetWindowScreenBounds();
+ // Now convert from screen to parent coordinates.
+ gfx::Point origin(bounds.origin());
+ BrowserView* browser_view = host()->browser_view();
+ ConvertPointToView(NULL, browser_view, &origin);
+ bounds.set_origin(origin);
+ // Finally, calculate the background image tiling offset.
+ origin = browser_view->OffsetPointForToolbarBackgroundImage(origin);
+
+ // First, we draw the background image for the whole dialog (3 images: left,
+ // middle and right). Note, that the window region has been set by the
+ // controller, so the whitespace in the left and right background images is
+ // actually outside the window region and is therefore not drawn. See
+ // FindInPageWidgetWin::CreateRoundedWindowEdges() for details.
+ ui::ThemeProvider* tp = GetThemeProvider();
+ canvas->TileImageInt(*tp->GetBitmapNamed(IDR_THEME_TOOLBAR), origin.x(),
+ origin.y(), 0, 0, bounds.width(), bounds.height());
+ return bounds;
+}
+
+void DropdownBarView::PaintDialogBorder(gfx::Canvas* canvas,
+ const gfx::Rect& bounds) const {
+ DCHECK(dialog_left_);
+ DCHECK(dialog_middle_);
+ DCHECK(dialog_right_);
+
+ canvas->DrawBitmapInt(*dialog_left_, 0, 0);
+
+ // Stretch the middle background to cover all of the area between the two
+ // other images.
+ canvas->TileImageInt(*dialog_middle_, dialog_left_->width(), 0,
+ bounds.width() - dialog_left_->width() - dialog_right_->width(),
+ dialog_middle_->height());
+
+ canvas->DrawBitmapInt(*dialog_right_, bounds.width() - dialog_right_->width(),
+ 0);
+}
+
+void DropdownBarView::PaintAnimatingEdges(gfx::Canvas* canvas,
+ const gfx::Rect& bounds) const {
+ if (animation_offset() > 0) {
+ // While animating we draw the curved edges at the point where the
+ // controller told us the top of the window is: |animation_offset()|.
+ canvas->TileImageInt(*dialog_left_, bounds.x(), animation_offset(),
+ dialog_left_->width(), kAnimatingEdgeHeight);
+ canvas->TileImageInt(*dialog_right_,
+ bounds.width() - dialog_right_->width(), animation_offset(),
+ dialog_right_->width(), kAnimatingEdgeHeight);
+ }
+}
diff --git a/chrome/browser/ui/views/dropdown_bar_view.h b/chrome/browser/ui/views/dropdown_bar_view.h
index cfd3377..a92dd43 100644
--- a/chrome/browser/ui/views/dropdown_bar_view.h
+++ b/chrome/browser/ui/views/dropdown_bar_view.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,9 +6,13 @@
#define CHROME_BROWSER_UI_VIEWS_DROPDOWN_BAR_VIEW_H_
#pragma once
-#include "views/view.h"
+#include "chrome/browser/ui/views/dropdown_bar_host.h"
+#include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
+#include "chrome/browser/ui/views/accessible_pane_view.h"
-class DropdownBarHost;
+namespace gfx {
+class Canvas;
+} // namespace gfx
////////////////////////////////////////////////////////////////////////////////
//
@@ -16,20 +20,15 @@ class DropdownBarHost;
// DropdownBarHost.
//
////////////////////////////////////////////////////////////////////////////////
-class DropdownBarView : public views::View {
+class DropdownBarView : public AccessiblePaneView,
+ public DropdownBarHostDelegate {
public:
- explicit DropdownBarView(DropdownBarHost* host)
- : host_(host),
- animation_offset_(0) {
- }
- virtual ~DropdownBarView() {}
-
- // Claims focus for the text field and selects its contents.
- virtual void SetFocusAndSelection(bool select_all) = 0;
+ explicit DropdownBarView(DropdownBarHost* host);
+ virtual ~DropdownBarView();
// Updates the view to let it know where the host is clipping the
// dropdown widget (while animating the opening or closing of the widget).
- void set_animation_offset(int offset) { animation_offset_ = offset; }
+ virtual void SetAnimationOffset(int offset) OVERRIDE;
// Returns the offset used while animating.
int animation_offset() const { return animation_offset_; }
@@ -38,6 +37,22 @@ class DropdownBarView : public views::View {
// Returns the DropdownBarHost that manages this view.
DropdownBarHost* host() const { return host_; }
+ // Assign border bitmaps for this drop down instance.
+ void SetDialogBorderBitmaps(const SkBitmap* dialog_left,
+ const SkBitmap* dialog_middle,
+ const SkBitmap* dialog_right);
+
+ // Paints the offset toolbar background over the widget area and returns the
+ // bounds of the widget.
+ gfx::Rect PaintOffsetToolbarBackground(gfx::Canvas* canvas);
+
+ // Paint the border for the drop down dialog given the ends and middle
+ // bitmaps.
+ void PaintDialogBorder(gfx::Canvas* canvas, const gfx::Rect& bounds) const;
+
+ // Special paint code for the edges when the drop down bar is animating.
+ void PaintAnimatingEdges(gfx::Canvas* canvas, const gfx::Rect& bounds) const;
+
private:
// The dropdown bar host that controls this view.
DropdownBarHost* host_;
@@ -48,6 +63,11 @@ class DropdownBarView : public views::View {
// in the right location.
int animation_offset_;
+ // The dialog border bitmaps.
+ const SkBitmap* dialog_left_;
+ const SkBitmap* dialog_middle_;
+ const SkBitmap* dialog_right_;
+
DISALLOW_COPY_AND_ASSIGN(DropdownBarView);
};
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc
index 3b36f96..26bed98 100644
--- a/chrome/browser/ui/views/find_bar_host.cc
+++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -36,7 +36,8 @@ FindBar* CreateFindBar(BrowserView* browser_view) {
FindBarHost::FindBarHost(BrowserView* browser_view)
: DropdownBarHost(browser_view),
find_bar_controller_(NULL) {
- Init(new FindBarView(this));
+ FindBarView* find_bar_view = new FindBarView(this);
+ Init(find_bar_view, find_bar_view);
}
FindBarHost::~FindBarHost() {
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc
index 8ecd4a1..957a028 100644
--- a/chrome/browser/ui/views/find_bar_view.cc
+++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -67,11 +67,6 @@ static const SkBitmap* kDialog_left = NULL;
static const SkBitmap* kDialog_middle = NULL;
static const SkBitmap* kDialog_right = NULL;
-// When we are animating, we draw only the top part of the left and right
-// edges to give the illusion that the find dialog is attached to the
-// window during this animation; this is the height of the items we draw.
-static const int kAnimatingEdgeHeight = 5;
-
// The background image for the Find text box, which we draw behind the Find box
// to provide the Chrome look to the edge of the text box.
static const SkBitmap* kBackground = NULL;
@@ -170,6 +165,7 @@ FindBarView::FindBarView(FindBarHost* host)
kBackground = rb.GetBitmapNamed(IDR_FIND_BOX_BACKGROUND);
kBackground_left = rb.GetBitmapNamed(IDR_FIND_BOX_BACKGROUND_LEFT);
}
+ SetDialogBorderBitmaps(kDialog_left, kDialog_middle, kDialog_right);
}
FindBarView::~FindBarView() {
@@ -246,25 +242,7 @@ void FindBarView::SetFocusAndSelection(bool select_all) {
void FindBarView::OnPaint(gfx::Canvas* canvas) {
SkPaint paint;
- // Determine the find bar size as well as the offset from which to tile the
- // toolbar background image. First, get the widget bounds.
- gfx::Rect bounds = GetWidget()->GetWindowScreenBounds();
- // Now convert from screen to parent coordinates.
- gfx::Point origin(bounds.origin());
- BrowserView* browser_view = host()->browser_view();
- ConvertPointToView(NULL, browser_view, &origin);
- bounds.set_origin(origin);
- // Finally, calculate the background image tiling offset.
- origin = browser_view->OffsetPointForToolbarBackgroundImage(origin);
-
- // First, we draw the background image for the whole dialog (3 images: left,
- // middle and right). Note, that the window region has been set by the
- // controller, so the whitespace in the left and right background images is
- // actually outside the window region and is therefore not drawn. See
- // FindInPageWidgetWin::CreateRoundedWindowEdges() for details.
- ui::ThemeProvider* tp = GetThemeProvider();
- canvas->TileImageInt(*tp->GetBitmapNamed(IDR_THEME_TOOLBAR), origin.x(),
- origin.y(), 0, 0, bounds.width(), bounds.height());
+ gfx::Rect bounds = PaintOffsetToolbarBackground(canvas);
// Now flip the canvas for the rest of the graphics if in RTL mode.
canvas->Save();
@@ -273,16 +251,7 @@ void FindBarView::OnPaint(gfx::Canvas* canvas) {
canvas->ScaleInt(-1, 1);
}
- canvas->DrawBitmapInt(*kDialog_left, 0, 0);
-
- // Stretch the middle background to cover all of the area between the two
- // other images.
- canvas->TileImageInt(*kDialog_middle, kDialog_left->width(), 0,
- bounds.width() - kDialog_left->width() - kDialog_right->width(),
- kDialog_middle->height());
-
- canvas->DrawBitmapInt(*kDialog_right, bounds.width() - kDialog_right->width(),
- 0);
+ PaintDialogBorder(canvas, bounds);
// Then we draw the background image for the Find Textfield. We start by
// calculating the position of background images for the Find text box.
@@ -300,15 +269,7 @@ void FindBarView::OnPaint(gfx::Canvas* canvas) {
back_button_origin.x() - find_text_x,
kBackground->height());
- if (animation_offset() > 0) {
- // While animating we draw the curved edges at the point where the
- // controller told us the top of the window is: |animation_offset()|.
- canvas->TileImageInt(*kDialog_left, bounds.x(), animation_offset(),
- kDialog_left->width(), kAnimatingEdgeHeight);
- canvas->TileImageInt(*kDialog_right,
- bounds.width() - kDialog_right->width(), animation_offset(),
- kDialog_right->width(), kAnimatingEdgeHeight);
- }
+ PaintAnimatingEdges(canvas, bounds);
canvas->Restore();
}
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 46c5917..f983b42 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -41,10 +41,15 @@
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/browser/ui/tabs/tab_menu_model.h"
#include "chrome/browser/ui/toolbar/wrench_menu_model.h"
#include "chrome/browser/ui/view_ids.h"
#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
#include "chrome/browser/ui/views/browser_dialogs.h"
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view.h"
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h"
+#include "chrome/browser/ui/views/compact_nav/compact_navigation_bar.h"
+#include "chrome/browser/ui/views/compact_nav/compact_options_bar.h"
#include "chrome/browser/ui/views/default_search_view.h"
#include "chrome/browser/ui/views/download/download_in_progress_dialog_view.h"
#include "chrome/browser/ui/views/download/download_shelf_view.h"
@@ -78,6 +83,7 @@
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "grit/theme_resources.h"
+#include "grit/theme_resources_standard.h"
#include "grit/webkit_resources.h"
#include "ui/base/accessibility/accessible_view_state.h"
#include "ui/base/l10n/l10n_util.h"
@@ -304,6 +310,9 @@ BrowserView::BrowserView(Browser* browser)
active_bookmark_bar_(NULL),
tabstrip_(NULL),
toolbar_(NULL),
+ compact_navigation_bar_(NULL),
+ compact_options_bar_(NULL),
+ compact_spacer_(NULL),
infobar_container_(NULL),
sidebar_container_(NULL),
sidebar_split_(NULL),
@@ -378,6 +387,11 @@ BrowserView* BrowserView::GetBrowserViewForNativeWindow(
gfx::Rect BrowserView::GetToolbarBounds() const {
gfx::Rect toolbar_bounds(toolbar_->bounds());
+ // In compact navigation mode, the spacer essentially replaces the toolbar.
+ // We must provide it's height in order to have the client area divider paint
+ // properly.
+ if (UseCompactNavigationBar())
+ toolbar_bounds = compact_spacer_->bounds();
if (toolbar_bounds.IsEmpty())
return toolbar_bounds;
// When using vertical tabs, the toolbar appears to extend behind the tab
@@ -401,6 +415,14 @@ gfx::Rect BrowserView::GetFindBarBoundingBox() const {
return GetBrowserViewLayout()->GetFindBarBoundingBox();
}
+gfx::Rect BrowserView::GetCompactNavigationBarBounds() const {
+ return compact_navigation_bar_->bounds();
+}
+
+gfx::Rect BrowserView::GetCompactOptionsBarBounds() const {
+ return compact_options_bar_->bounds();
+}
+
int BrowserView::GetTabStripHeight() const {
// We want to return tabstrip_->height(), but we might be called in the midst
// of layout, when that hasn't yet been updated to reflect the current state.
@@ -432,6 +454,10 @@ bool BrowserView::UseVerticalTabs() const {
return browser_->tabstrip_model()->delegate()->UseVerticalTabs();
}
+bool BrowserView::UseCompactNavigationBar() const {
+ return browser_->tabstrip_model()->delegate()->UseCompactNavigationBar();
+}
+
bool BrowserView::IsOffTheRecord() const {
return browser_->profile()->IsOffTheRecord();
}
@@ -707,7 +733,7 @@ void BrowserView::UpdateLoadingAnimations(bool should_animate) {
}
void BrowserView::SetStarredState(bool is_starred) {
- toolbar_->location_bar()->SetStarToggled(is_starred);
+ GetLocationBarView()->SetStarToggled(is_starred);
}
gfx::Rect BrowserView::GetRestoredBounds() const {
@@ -754,11 +780,16 @@ void BrowserView::RestoreFocus() {
}
LocationBar* BrowserView::GetLocationBar() const {
- return toolbar_->location_bar();
+ return GetLocationBarView();
}
void BrowserView::SetFocusToLocationBar(bool select_all) {
- LocationBarView* location_bar = toolbar_->location_bar();
+ if (UseCompactNavigationBar()) {
+ // If focus ever goes to the location bar, we should make sure it is shown
+ // in compact mode. This includes all accelerators that move focus there.
+ ShowCompactLocationBarUnderSelectedTab();
+ }
+ LocationBarView* location_bar = GetLocationBarView();
if (location_bar->IsFocusableInRootView()) {
// Location bar got focus.
location_bar->FocusLocation(select_all);
@@ -772,20 +803,42 @@ void BrowserView::SetFocusToLocationBar(bool select_all) {
}
void BrowserView::UpdateReloadStopState(bool is_loading, bool force) {
- toolbar_->reload_button()->ChangeMode(
+ ReloadButton* reload_button = NULL;
+ if (UseCompactNavigationBar()) {
+ reload_button = compact_location_bar_view_host_->
+ GetCompactLocationBarView()->reload_button();
+ } else {
+ reload_button = toolbar_->reload_button();
+ }
+ reload_button->ChangeMode(
is_loading ? ReloadButton::MODE_STOP : ReloadButton::MODE_RELOAD, force);
}
void BrowserView::UpdateToolbar(TabContentsWrapper* contents,
bool should_restore_state) {
- toolbar_->Update(contents->tab_contents(), should_restore_state);
+ if (UseCompactNavigationBar()) {
+ if (compact_location_bar_view_host_->IsVisible()) {
+ compact_location_bar_view_host_->Update(
+ should_restore_state ? contents->tab_contents() : NULL, true);
+ }
+ } else {
+ toolbar_->Update(contents->tab_contents(), should_restore_state);
+ }
}
void BrowserView::FocusToolbar() {
// Start the traversal within the main toolbar, passing it the storage id
// of the view where focus should be returned if the user exits the toolbar.
SaveFocusedView();
- toolbar_->SetPaneFocus(last_focused_view_storage_id_, NULL);
+ if (UseCompactNavigationBar()) {
+ if (!compact_location_bar_view_host_->IsVisible())
+ compact_location_bar_view_host_->UpdateOnTabChange(
+ browser()->active_index(), true);
+ compact_location_bar_view_host_->GetCompactLocationBarView()->SetPaneFocus(
+ last_focused_view_storage_id_, NULL);
+ } else {
+ toolbar_->SetPaneFocus(last_focused_view_storage_id_, NULL);
+ }
}
void BrowserView::FocusBookmarksToolbar() {
@@ -807,6 +860,7 @@ void BrowserView::FocusAppMenu() {
RestoreFocus();
} else {
SaveFocusedView();
+ // TODO(mad): find out how to add this to compact nav view.
toolbar_->SetPaneFocusAndFocusAppMenu(last_focused_view_storage_id_);
}
}
@@ -906,8 +960,12 @@ bool BrowserView::IsTabStripEditable() const {
}
bool BrowserView::IsToolbarVisible() const {
- return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
- browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
+ if (UseCompactNavigationBar()) {
+ return false;
+ } else {
+ return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) ||
+ browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
+ }
}
void BrowserView::DisableInactiveFrame() {
@@ -951,6 +1009,13 @@ void BrowserView::ShowUpdateChromeDialog() {
UpdateRecommendedMessageBox::ShowMessageBox(GetWindow()->GetNativeWindow());
}
+void BrowserView::ShowCompactLocationBarUnderSelectedTab() {
+ if (!UseCompactNavigationBar())
+ return;
+ compact_location_bar_view_host_->UpdateOnTabChange(browser()->active_index(),
+ true);
+}
+
void BrowserView::ShowTaskManager() {
browser::ShowTaskManager();
}
@@ -960,7 +1025,7 @@ void BrowserView::ShowBackgroundPages() {
}
void BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) {
- toolbar_->location_bar()->ShowStarBubble(url, !already_bookmarked);
+ GetLocationBarView()->ShowStarBubble(url, !already_bookmarked);
}
void BrowserView::SetDownloadShelfVisible(bool visible) {
@@ -1061,6 +1126,7 @@ void BrowserView::ShowPageInfo(Profile* profile,
}
void BrowserView::ShowAppMenu() {
+ // TODO(mad): find out how to add this to compact nav view.
toolbar_->app_menu()->Activate();
}
@@ -1156,6 +1222,16 @@ void BrowserView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
#endif
}
+void BrowserView::ToggleUseCompactNavigationBar() {
+ bool use_compact_navigation_bar = UseCompactNavigationBar();
+ // Compact Navigation Bar only works with horizontal tabs for now!
+ if (use_compact_navigation_bar && UseVerticalTabs())
+ browser()->ExecuteCommand(IDC_TOGGLE_VERTICAL_TABS);
+ compact_location_bar_view_host_->SetEnabled(use_compact_navigation_bar);
+ compact_location_bar_view_host_->Hide(!use_compact_navigation_bar);
+ Layout();
+}
+
// TODO(devint): http://b/issue?id=1117225 Cut, Copy, and Paste are always
// enabled in the page menu regardless of whether the command will do
// anything. When someone selects the menu item, we just act as if they hit
@@ -1179,6 +1255,10 @@ void BrowserView::Paste() {
}
void BrowserView::ToggleTabStripMode() {
+ // Compact Navigation Bar only works with horizontal tabs for now!
+ if (UseVerticalTabs() && UseCompactNavigationBar())
+ browser()->ExecuteCommand(IDC_COMPACT_NAVBAR);
+
InitTabStrip(browser_->tabstrip_model());
frame_->TabStripDisplayModeChanged();
}
@@ -1242,7 +1322,12 @@ BookmarkBarView* BrowserView::GetBookmarkBarView() const {
}
LocationBarView* BrowserView::GetLocationBarView() const {
- return toolbar_->location_bar();
+ if (UseCompactNavigationBar()) {
+ return compact_location_bar_view_host_->GetCompactLocationBarView()->
+ location_bar_view();
+ } else {
+ return toolbar_ ? toolbar_->location_bar() : NULL;
+ }
}
views::View* BrowserView::GetTabContentsContainerView() const {
@@ -1563,8 +1648,9 @@ void BrowserView::OnWidgetMove() {
browser::HideBookmarkBubbleView();
// Close the omnibox popup, if any.
- if (toolbar_ && toolbar_->location_bar())
- toolbar_->location_bar()->location_entry()->ClosePopup();
+ LocationBarView* location_bar_view = GetLocationBarView();
+ if (location_bar_view)
+ location_bar_view->location_entry()->ClosePopup();
}
///////////////////////////////////////////////////////////////////////////////
@@ -1843,6 +1929,27 @@ void BrowserView::Init() {
browser_->tabstrip_model()->AddObserver(aeropeek_manager_.get());
}
#endif
+ // Only create our compact navigation classes if the switch is enabled. Note
+ // that we directly check the switch and not the pref as the switch may be on
+ // and the pref could be off (currently not selected in the context menu).
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableCompactNavigation)) {
+ compact_location_bar_view_host_.reset(new CompactLocationBarViewHost(this));
+ compact_navigation_bar_ = new CompactNavigationBar(this);
+ compact_navigation_bar_->SetID(VIEW_ID_COMPACT_NAV_BAR);
+ AddChildView(compact_navigation_bar_);
+ compact_navigation_bar_->Init();
+ compact_options_bar_ = new CompactOptionsBar(this);
+ compact_options_bar_->SetID(VIEW_ID_COMPACT_OPT_BAR);
+ AddChildView(compact_options_bar_);
+ compact_options_bar_->Init();
+ }
+
+ // Use an empty view for the spacer since all it does is that it replaces the
+ // toolbar area in compact navigation mode.
+ compact_spacer_ = new views::View();
+ compact_spacer_->SetID(VIEW_ID_COMPACT_NAV_BAR_SPACER);
+ AddChildView(compact_spacer_);
// We're now initialized and ready to process Layout requests.
ignore_layout_ = false;
@@ -2111,7 +2218,7 @@ void BrowserView::ProcessFullscreen(bool fullscreen) {
// * Ignoring all intervening Layout() calls, which resize the webpage and
// thus are slow and look ugly
ignore_layout_ = true;
- LocationBarView* location_bar = toolbar_->location_bar();
+ LocationBarView* location_bar = GetLocationBarView();
#if defined(OS_WIN)
OmniboxViewWin* omnibox_view =
static_cast<OmniboxViewWin*>(location_bar->location_entry());
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index c80cee6..b15312f 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -16,6 +16,7 @@
#include "chrome/browser/tabs/tab_strip_model_observer.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/views/compact_nav/compact_location_bar_view_host.h"
#include "chrome/browser/ui/views/frame/browser_bubble_host.h"
#include "chrome/browser/ui/views/frame/browser_frame.h"
#include "chrome/browser/ui/views/infobars/infobar_container.h"
@@ -44,6 +45,9 @@ class Browser;
class BrowserBubble;
class BrowserViewLayout;
class ContentsContainer;
+class CompactLocationBar;
+class CompactNavigationBar;
+class CompactOptionsBar;
class DownloadShelfView;
class EncodingMenuModel;
class FullscreenExitBubble;
@@ -105,7 +109,9 @@ class BrowserView : public BrowserBubbleHost,
// Returns the apparent bounds of the toolbar, in BrowserView coordinates.
// These differ from |toolbar_.bounds()| in that they match where the toolbar
// background image is drawn -- slightly outside the "true" bounds
- // horizontally, and, when using vertical tabs, behind the tab column.
+ // horizontally, and, when using vertical tabs, behind the tab column. Note
+ // that this returns the bounds for the toolbar area, which could just be the
+ // spacer bounds if in compact navigation mode.
virtual gfx::Rect GetToolbarBounds() const;
// Returns the bounds of the content area, in the coordinates of the
@@ -119,6 +125,14 @@ class BrowserView : public BrowserBubbleHost,
// window.
gfx::Rect GetFindBarBoundingBox() const;
+ // Returns the bounds of the compact navigation bar (back and forward
+ // buttons).
+ gfx::Rect GetCompactNavigationBarBounds() const;
+
+ // Returns the bounds of the compact options bar (browser actions and app
+ // menu).
+ gfx::Rect GetCompactOptionsBarBounds() const;
+
// Returns the preferred height of the TabStrip. Used to position the OTR
// avatar icon.
virtual int GetTabStripHeight() const;
@@ -144,6 +158,9 @@ class BrowserView : public BrowserBubbleHost,
// Returns true if the vertical tabstrip is in use.
bool UseVerticalTabs() const;
+ // Returns true if the compact navigation bar is in use.
+ bool UseCompactNavigationBar() const;
+
// Returns true if the profile associated with this Browser window is
// incognito.
bool IsOffTheRecord() const;
@@ -226,6 +243,11 @@ class BrowserView : public BrowserBubbleHost,
// when a new browser window is created.
void RestoreFocus();
+ // Access the CompactLocationBarHost.
+ CompactLocationBarViewHost* compact_location_bar_view_host() {
+ return compact_location_bar_view_host_.get();
+ }
+
// Overridden from BrowserWindow:
virtual void Show() OVERRIDE;
virtual void ShowInactive() OVERRIDE;
@@ -304,6 +326,7 @@ class BrowserView : public BrowserBubbleHost,
OVERRIDE;
virtual void ShowCreateChromeAppShortcutsDialog(
Profile*, const Extension* app) OVERRIDE;
+ virtual void ToggleUseCompactNavigationBar() OVERRIDE;
virtual void Cut() OVERRIDE;
virtual void Copy() OVERRIDE;
virtual void Paste() OVERRIDE;
@@ -436,6 +459,7 @@ class BrowserView : public BrowserBubbleHost,
private:
friend class BrowserViewLayout;
+ friend class CompactLocationBarHostTest;
FRIEND_TEST_ALL_PREFIXES(BrowserViewsAccessibilityTest,
TestAboutChromeViewAccObj);
@@ -526,7 +550,10 @@ class BrowserView : public BrowserBubbleHost,
// Shows the about chrome modal dialog and returns the Window object.
views::Window* DoShowAboutChromeDialog();
- // Set the value of |toolbar_| and hook it into the views hiearchy
+ // Shows the Compact Location Bar under the selected tab.
+ void ShowCompactLocationBarUnderSelectedTab();
+
+ // Set the value of |toolbar_| and hook it into the views hierarchy
void SetToolbar(ToolbarView* toolbar);
// Last focused view that issued a tab traversal.
@@ -590,6 +617,19 @@ class BrowserView : public BrowserBubbleHost,
// The Toolbar containing the navigation buttons, menus and the address bar.
ToolbarView* toolbar_;
+ // CompactNavigationBar view.
+ CompactNavigationBar* compact_navigation_bar_;
+
+ // CompactOptionsBar view.
+ CompactOptionsBar* compact_options_bar_;
+
+ // CompactLocationBarHost.
+ scoped_ptr<CompactLocationBarViewHost> compact_location_bar_view_host_;
+
+ // A spacer under the tap strip used when the compact navigation bar
+ // is active.
+ views::View* compact_spacer_;
+
// The Bookmark Bar View for this window. Lazily created.
scoped_ptr<BookmarkBarView> bookmark_bar_view_;
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index ff63aa9..1cde2ac 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -34,6 +34,29 @@ namespace {
const int kTabShadowSize = 2;
// The vertical overlap between the TabStrip and the Toolbar.
const int kToolbarTabStripVerticalOverlap = 3;
+// The vertical size of the space between the content area and the tabstrip that
+// is inserted in compact navigation mode. Note that we need to use a height
+// that includes the overlap to get the visible height we want, in order to
+// match how the toolbar overlaps the tabstrip.
+const int kCompactNavbarSpacerVisibleHeight = 4;
+const int kCompactNavbarSpacerHeight =
+ kCompactNavbarSpacerVisibleHeight + kToolbarTabStripVerticalOverlap;
+// The size of the padding between the compact navigation bar and the tab strip.
+const int kCompactNavbarHorizontalPadding = 2;
+// The number of pixels the bookmark bar should overlap the spacer by if the
+// spacer is visible.
+const int kSpacerBookmarkBarOverlap = 1;
+
+// Combines View::ConvertPointToView and View::HitTest for a given |point|.
+// Converts |point| from |src| to |dst| and hit tests it against |dst|. The
+// converted |point| can then be retrieved and used for additional tests.
+bool ConvertedHitTest(views::View* src, views::View* dst, gfx::Point* point) {
+ DCHECK(src);
+ DCHECK(dst);
+ DCHECK(point);
+ views::View::ConvertPointToView(src, dst, point);
+ return dst->HitTest(*point);
+}
} // namespace
@@ -46,6 +69,9 @@ BrowserViewLayout::BrowserViewLayout()
contents_split_(NULL),
contents_container_(NULL),
infobar_container_(NULL),
+ compact_navigation_bar_(NULL),
+ compact_options_bar_(NULL),
+ compact_spacer_(NULL),
download_shelf_(NULL),
active_bookmark_bar_(NULL),
browser_view_(NULL),
@@ -138,20 +164,29 @@ int BrowserViewLayout::NonClientHitTest(
gfx::Point point_in_browser_view_coords(point);
views::View::ConvertPointToView(
parent, browser_view_, &point_in_browser_view_coords);
+ gfx::Point test_point(point);
// Determine if the TabStrip exists and is capable of being clicked on. We
// might be a popup window without a TabStrip.
if (browser_view_->IsTabStripVisible()) {
// See if the mouse pointer is within the bounds of the TabStrip.
- gfx::Point point_in_tabstrip_coords(point);
- views::View::ConvertPointToView(parent, tabstrip_,
- &point_in_tabstrip_coords);
- if (tabstrip_->HitTest(point_in_tabstrip_coords)) {
- if (tabstrip_->IsPositionInWindowCaption(point_in_tabstrip_coords))
+ if (ConvertedHitTest(parent, tabstrip_, &test_point)) {
+ if (tabstrip_->IsPositionInWindowCaption(test_point))
return HTCAPTION;
return HTCLIENT;
}
+ // If the tabstrip is visible and we are in compact navigation mode, test
+ // against the compact navigation and option bars.
+ if (browser_view_->UseCompactNavigationBar()) {
+ test_point = point;
+ if (ConvertedHitTest(parent, compact_navigation_bar_, &test_point))
+ return HTCLIENT;
+ test_point = point;
+ if (ConvertedHitTest(parent, compact_options_bar_, &test_point))
+ return HTCLIENT;
+ }
+
// The top few pixels of the TabStrip are a drop-shadow - as we're pretty
// starved of dragable area, let's give it to window dragging (this also
// makes sense visually).
@@ -204,6 +239,9 @@ void BrowserViewLayout::Installed(views::View* host) {
download_shelf_ = NULL;
active_bookmark_bar_ = NULL;
tabstrip_ = NULL;
+ compact_navigation_bar_ = NULL;
+ compact_options_bar_ = NULL;
+ compact_spacer_ = NULL;
browser_view_ = static_cast<BrowserView*>(host);
}
@@ -234,6 +272,15 @@ void BrowserViewLayout::ViewAdded(views::View* host, views::View* view) {
case VIEW_ID_TAB_STRIP:
tabstrip_ = static_cast<AbstractTabStripView*>(view);
break;
+ case VIEW_ID_COMPACT_NAV_BAR_SPACER:
+ compact_spacer_ = view;
+ break;
+ case VIEW_ID_COMPACT_NAV_BAR:
+ compact_navigation_bar_ = view;
+ break;
+ case VIEW_ID_COMPACT_OPT_BAR:
+ compact_options_bar_ = view;
+ break;
}
}
@@ -247,7 +294,7 @@ void BrowserViewLayout::ViewRemoved(views::View* host, views::View* view) {
void BrowserViewLayout::Layout(views::View* host) {
vertical_layout_rect_ = browser_view_->GetLocalBounds();
- int top = LayoutTabStrip();
+ int top = LayoutTabStripRegion();
if (browser_view_->IsTabStripVisible() && !browser_view_->UseVerticalTabs()) {
tabstrip_->SetBackgroundOffset(gfx::Point(
tabstrip_->GetMirroredX() + browser_view_->GetMirroredX(),
@@ -268,6 +315,11 @@ void BrowserViewLayout::Layout(views::View* host) {
browser()->GetFindBarController()->find_bar()->MoveWindowIfNecessary(
gfx::Rect(), true);
}
+ if (browser()->UseCompactNavigationBar()) {
+ DCHECK(browser_view_->compact_location_bar_view_host());
+ browser_view_->compact_location_bar_view_host()->MoveWindowIfNecessary(
+ gfx::Rect(), true);
+ }
}
// Return the preferred size which is the size required to give each
@@ -287,13 +339,19 @@ const Browser* BrowserViewLayout::browser() const {
return browser_view_->browser();
}
-int BrowserViewLayout::LayoutTabStrip() {
+int BrowserViewLayout::LayoutTabStripRegion() {
if (!browser_view_->IsTabStripVisible()) {
+ if (compact_navigation_bar_ && compact_options_bar_) {
+ compact_navigation_bar_->SetVisible(false);
+ compact_options_bar_->SetVisible(false);
+ }
tabstrip_->SetVisible(false);
tabstrip_->SetBounds(0, 0, 0, 0);
return 0;
}
+ // This retrieves the bounds for the tab strip based on whether or not we show
+ // anything to the left of it, like the incognito avatar.
gfx::Rect tabstrip_bounds(
browser_view_->frame()->GetBoundsForTabStrip(tabstrip_));
gfx::Point tabstrip_origin(tabstrip_bounds.origin());
@@ -301,6 +359,41 @@ int BrowserViewLayout::LayoutTabStrip() {
&tabstrip_origin);
tabstrip_bounds.set_origin(tabstrip_origin);
+ // If we are in compact nav mode, we want to reduce the tab strip bounds from
+ // both ends enough to lay out the compact navigation and options bars. We
+ // check the pointers to see if the mode is available, and then check the pref
+ // to see if the mode is enabled (and therefore if the additional bars should
+ // be made visible).
+ if (compact_navigation_bar_ && compact_options_bar_) {
+ compact_navigation_bar_->SetVisible(
+ browser_view_->UseCompactNavigationBar());
+ compact_options_bar_->SetVisible(browser_view_->UseCompactNavigationBar());
+
+ if (compact_navigation_bar_->IsVisible()) {
+ gfx::Rect cnav_bar_bounds;
+ gfx::Size cnav_bar_size = compact_navigation_bar_->GetPreferredSize();
+ cnav_bar_bounds.set_origin(tabstrip_bounds.origin());
+ cnav_bar_bounds.set_size(cnav_bar_size);
+ compact_navigation_bar_->SetBoundsRect(cnav_bar_bounds);
+
+ // The options bar is flush right of the tab strip region.
+ gfx::Rect copt_bar_bounds;
+ gfx::Size copt_bar_size = compact_options_bar_->GetPreferredSize();
+ copt_bar_bounds.set_x(std::max(0, tabstrip_bounds.right() -
+ copt_bar_size.width()));
+ copt_bar_bounds.set_y(tabstrip_origin.y());
+ copt_bar_bounds.set_size(copt_bar_size);
+ compact_options_bar_->SetBoundsRect(copt_bar_bounds);
+
+ // Reduce the bounds of the tab strip accordingly.
+ tabstrip_bounds.set_x(tabstrip_bounds.x() + cnav_bar_size.width() +
+ kCompactNavbarHorizontalPadding);
+ tabstrip_bounds.set_width(std::max(0, tabstrip_bounds.width() -
+ cnav_bar_size.width() - copt_bar_size.width() -
+ kCompactNavbarHorizontalPadding * 2));
+ }
+ }
+
if (browser_view_->UseVerticalTabs())
vertical_layout_rect_.Inset(tabstrip_bounds.width(), 0, 0, 0);
@@ -312,16 +405,26 @@ int BrowserViewLayout::LayoutTabStrip() {
int BrowserViewLayout::LayoutToolbar(int top) {
int browser_view_width = vertical_layout_rect_.width();
- bool visible = browser_view_->IsToolbarVisible();
- toolbar_->location_bar()->SetFocusable(visible);
+ bool toolbar_visible = browser_view_->IsToolbarVisible();
+ toolbar_->location_bar()->SetFocusable(toolbar_visible);
int y = top;
if (!browser_view_->UseVerticalTabs()) {
- y -= ((visible && browser_view_->IsTabStripVisible()) ?
- kToolbarTabStripVerticalOverlap : 0);
+ y -= ((toolbar_visible || browser_view_->UseCompactNavigationBar()) &&
+ browser_view_->IsTabStripVisible()) ?
+ kToolbarTabStripVerticalOverlap : 0;
}
- int height = visible ? toolbar_->GetPreferredSize().height() : 0;
- toolbar_->SetVisible(visible);
+ int height = toolbar_visible ? toolbar_->GetPreferredSize().height() : 0;
+ toolbar_->SetVisible(toolbar_visible);
toolbar_->SetBounds(vertical_layout_rect_.x(), y, browser_view_width, height);
+
+ // The spacer essentially replaces the toolbar when in compact mode.
+ if (browser_view_->UseCompactNavigationBar()) {
+ compact_spacer_->SetVisible(!toolbar_visible);
+ compact_spacer_->SetBounds(vertical_layout_rect_.x(), y, browser_view_width,
+ toolbar_visible ? 0 : kCompactNavbarSpacerHeight);
+ height = kCompactNavbarSpacerHeight;
+ }
+
return y + height;
}
@@ -351,8 +454,12 @@ int BrowserViewLayout::LayoutBookmarkBar(int top) {
active_bookmark_bar_->set_infobar_visible(InfobarVisible());
int bookmark_bar_height = active_bookmark_bar_->GetPreferredSize().height();
- y -= views::NonClientFrameView::kClientEdgeThickness +
- active_bookmark_bar_->GetToolbarOverlap(false);
+ if (!browser_view_->UseCompactNavigationBar()) {
+ y -= views::NonClientFrameView::kClientEdgeThickness +
+ active_bookmark_bar_->GetToolbarOverlap(false);
+ } else {
+ y -= kSpacerBookmarkBarOverlap;
+ }
active_bookmark_bar_->SetVisible(true);
active_bookmark_bar_->SetBounds(vertical_layout_rect_.x(), y,
vertical_layout_rect_.width(),
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.h b/chrome/browser/ui/views/frame/browser_view_layout.h
index 728b97c..e7a3742 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.h
+++ b/chrome/browser/ui/views/frame/browser_view_layout.h
@@ -62,9 +62,11 @@ class BrowserViewLayout : public views::LayoutManager {
Browser* browser();
const Browser* browser() const;
- // Layout the TabStrip, returns the coordinate of the bottom of the TabStrip,
- // for laying out subsequent controls.
- virtual int LayoutTabStrip();
+ // Layout the tab strip region, returns the coordinate of the bottom of the
+ // TabStrip, for laying out subsequent controls. This also lays out the
+ // compact navigation and options bars if the browser is in compact navigation
+ // mode.
+ virtual int LayoutTabStripRegion();
// Layout the following controls, starting at |top|, returns the coordinate
// of the bottom of the control, for laying out the next control.
@@ -112,6 +114,9 @@ class BrowserViewLayout : public views::LayoutManager {
views::SingleSplitView* contents_split_;
ContentsContainer* contents_container_;
views::View* infobar_container_;
+ views::View* compact_navigation_bar_;
+ views::View* compact_options_bar_;
+ views::View* compact_spacer_;
DownloadShelfView* download_shelf_;
BookmarkBarView* active_bookmark_bar_;
diff --git a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
index 69f3565..da4ca70 100644
--- a/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/ui/views/frame/opaque_browser_frame_view.cc
@@ -106,6 +106,19 @@ const int kMenuDisplayOffset = 7;
const int kProfileTagYPosition = 1;
// Offset y position of profile button and tag by this amount when maximized.
const int kProfileElementMaximizedYOffset = 6;
+
+// Converts |bounds| from |src|'s coordinate system to |dst|, and checks if
+// |pt| is contained within.
+bool ConvertedContainsCheck(gfx::Rect bounds, const views::View* src,
+ const views::View* dst, const gfx::Point& pt) {
+ DCHECK(src);
+ DCHECK(dst);
+ gfx::Point origin(bounds.origin());
+ views::View::ConvertPointToView(src, dst, &origin);
+ bounds.set_origin(origin);
+ return bounds.Contains(pt);
+}
+
}
///////////////////////////////////////////////////////////////////////////////
@@ -443,7 +456,8 @@ void OpaqueBrowserFrameView::OnPaint(gfx::Canvas* canvas) {
else
PaintRestoredFrameBorder(canvas);
PaintTitleBar(canvas);
- if (browser_view_->IsToolbarVisible())
+ if (browser_view_->IsToolbarVisible() ||
+ browser_view_->UseCompactNavigationBar())
PaintToolbarBackground(canvas);
if (browser_view_->ShouldShowOffTheRecordAvatar())
PaintOTRAvatar(canvas);
@@ -477,6 +491,22 @@ bool OpaqueBrowserFrameView::HitTest(const gfx::Point& l) const {
return false;
}
+ // Claim it only if we're also not in the compact navigation buttons.
+ if (browser_view_->UseCompactNavigationBar()) {
+ if (ConvertedContainsCheck(browser_view_->GetCompactNavigationBarBounds(),
+ frame_->GetWindow()->client_view(),
+ static_cast<const View*>(this),
+ l)) {
+ return false;
+ }
+ if (ConvertedContainsCheck(browser_view_->GetCompactOptionsBarBounds(),
+ frame_->GetWindow()->client_view(),
+ static_cast<const View*>(this),
+ l)) {
+ return false;
+ }
+ }
+
// We convert from our parent's coordinates since we assume we fill its bounds
// completely. We need to do this since we're not a parent of the tabstrip,
// meaning ConvertPointToView would otherwise return something bogus.
@@ -962,9 +992,10 @@ void OpaqueBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
SkColor toolbar_color = tp->GetColor(ThemeService::COLOR_TOOLBAR);
- if (browser_view_->IsToolbarVisible()) {
+ if (browser_view_->IsToolbarVisible() ||
+ browser_view_->UseCompactNavigationBar()) {
// The client edge images always start below the toolbar corner images. The
- // client edge filled rects start there or at the bottom of the tooolbar,
+ // client edge filled rects start there or at the bottom of the toolbar,
// whichever is shorter.
gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
image_top += toolbar_bounds.y() +
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index d64fc59..05262f5 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -120,7 +120,8 @@ LocationBarView::LocationBarView(Profile* profile,
mode_(mode),
show_focus_rect_(false),
bubble_type_(FirstRun::MINIMAL_BUBBLE),
- template_url_model_(NULL) {
+ template_url_model_(NULL),
+ animation_offset_(0) {
DCHECK(profile_);
SetID(VIEW_ID_LOCATION_BAR);
SetFocusable(true);
@@ -269,6 +270,15 @@ SkColor LocationBarView::GetColor(ToolbarModel::SecurityLevel security_level,
}
}
+// DropdownBarHostDelegate
+void LocationBarView::SetFocusAndSelection(bool select_all) {
+ FocusLocation(select_all);
+}
+
+void LocationBarView::SetAnimationOffset(int offset) {
+ animation_offset_ = offset;
+}
+
void LocationBarView::Update(const TabContents* tab_for_state_restoring) {
bool star_enabled = star_view_ && !model_->input_in_progress() &&
edit_bookmarks_enabled_.GetValue();
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index 4d6ac50..6947520 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -18,6 +18,8 @@
#include "chrome/browser/search_engines/template_url_model_observer.h"
#include "chrome/browser/ui/omnibox/location_bar.h"
#include "chrome/browser/ui/toolbar/toolbar_model.h"
+#include "chrome/browser/ui/views/dropdown_bar_host.h"
+#include "chrome/browser/ui/views/dropdown_bar_host_delegate.h"
#include "chrome/browser/ui/views/extensions/extension_popup.h"
#include "ui/gfx/font.h"
#include "ui/gfx/rect.h"
@@ -48,7 +50,7 @@ class TemplateURLModel;
namespace views {
class HorizontalPainter;
class Label;
-};
+} // namespace views
#if defined(OS_WIN)
class SuggestedTextView;
@@ -67,12 +69,20 @@ class LocationBarView : public LocationBar,
public views::View,
public views::DragController,
public AutocompleteEditController,
+ public DropdownBarHostDelegate,
public TemplateURLModelObserver,
public NotificationObserver {
public:
// The location bar view's class name.
static const char kViewClassName[];
+ // DropdownBarHostDelegate
+ virtual void SetFocusAndSelection(bool select_all) OVERRIDE;
+ virtual void SetAnimationOffset(int offset) OVERRIDE;
+
+ // Returns the offset used while animating.
+ int animation_offset() const { return animation_offset_; }
+
class Delegate {
public:
// Should return the current tab contents.
@@ -412,6 +422,12 @@ class LocationBarView : public LocationBar,
// Tracks this preference to determine whether bookmark editing is allowed.
BooleanPrefMember edit_bookmarks_enabled_;
+ // While animating, the host clips the widget and draws only the bottom
+ // part of it. The view needs to know the pixel offset at which we are drawing
+ // the widget so that we can draw the curved edges that attach to the toolbar
+ // in the right location.
+ int animation_offset_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(LocationBarView);
};
diff --git a/chrome/browser/ui/views/tabs/base_tab.cc b/chrome/browser/ui/views/tabs/base_tab.cc
index 9368313..79c0189 100644
--- a/chrome/browser/ui/views/tabs/base_tab.cc
+++ b/chrome/browser/ui/views/tabs/base_tab.cc
@@ -301,6 +301,8 @@ bool BaseTab::OnMousePressed(const views::MouseEvent& event) {
}
} else if (!IsSelected()) {
controller()->SelectTab(this);
+ } else if (IsActive()) {
+ controller()->ClickActiveTab(this);
}
controller()->MaybeStartDrag(this, event);
}
diff --git a/chrome/browser/ui/views/tabs/base_tab_strip.cc b/chrome/browser/ui/views/tabs/base_tab_strip.cc
index 2a980df..8178edd 100644
--- a/chrome/browser/ui/views/tabs/base_tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/base_tab_strip.cc
@@ -375,6 +375,13 @@ BaseTab* BaseTabStrip::GetTabAt(BaseTab* tab,
return GetTabAtLocal(local_point);
}
+void BaseTabStrip::ClickActiveTab(const BaseTab* tab) const {
+ DCHECK(IsActiveTab(tab));
+ int index = GetModelIndexOfBaseTab(tab);
+ if (controller() && IsValidModelIndex(index))
+ controller()->ClickActiveTab(index);
+}
+
void BaseTabStrip::Layout() {
// Only do a layout if our size changed.
if (last_layout_size_ == size())
diff --git a/chrome/browser/ui/views/tabs/base_tab_strip.h b/chrome/browser/ui/views/tabs/base_tab_strip.h
index 14254cb..ff82b58 100644
--- a/chrome/browser/ui/views/tabs/base_tab_strip.h
+++ b/chrome/browser/ui/views/tabs/base_tab_strip.h
@@ -133,6 +133,7 @@ class BaseTabStrip : public AbstractTabStripView,
virtual bool EndDrag(bool canceled) OVERRIDE;
virtual BaseTab* GetTabAt(BaseTab* tab,
const gfx::Point& tab_in_tab_coordinates) OVERRIDE;
+ virtual void ClickActiveTab(const BaseTab* tab) const OVERRIDE;
// View overrides:
virtual void Layout() OVERRIDE;
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
index b77e496..299dd7a 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -309,6 +309,11 @@ void BrowserTabStripController::CreateNewTab() {
model_->delegate()->AddBlankTab(true);
}
+void BrowserTabStripController::ClickActiveTab(int index) {
+ DCHECK(model_->active_index() == index);
+ model_->ActiveTabClicked(index);
+}
+
////////////////////////////////////////////////////////////////////////////////
// BrowserTabStripController, TabStripModelObserver implementation:
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
index 47fbad4..31e2af9 100644
--- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
+++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.h
@@ -63,6 +63,7 @@ class BrowserTabStripController : public TabStripController,
const GURL& url) OVERRIDE;
virtual bool IsCompatibleWith(BaseTabStrip* other) const OVERRIDE;
virtual void CreateNewTab() OVERRIDE;
+ virtual void ClickActiveTab(int index) OVERRIDE;
// TabStripModelObserver implementation:
virtual void TabInsertedAt(TabContentsWrapper* contents,
diff --git a/chrome/browser/ui/views/tabs/tab_controller.h b/chrome/browser/ui/views/tabs/tab_controller.h
index a95df6c..610e353 100644
--- a/chrome/browser/ui/views/tabs/tab_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_controller.h
@@ -65,6 +65,10 @@ class TabController {
virtual BaseTab* GetTabAt(BaseTab* tab,
const gfx::Point& tab_in_tab_coordinates) = 0;
+ // Informs that an active tab is selected when already active (ie - clicked
+ // when already active/foreground).
+ virtual void ClickActiveTab(const BaseTab* tab) const = 0;
+
protected:
virtual ~TabController() {}
};
diff --git a/chrome/browser/ui/views/tabs/tab_strip_controller.h b/chrome/browser/ui/views/tabs/tab_strip_controller.h
index 674431c..b97ca4a 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_strip_controller.h
@@ -81,6 +81,10 @@ class TabStripController {
// Creates the new tab.
virtual void CreateNewTab() = 0;
+
+ // Informs that an active tab is selected when already active (ie - clicked
+ // when already active/foreground).
+ virtual void ClickActiveTab(int index) = 0;
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/toolbar_view.cc b/chrome/browser/ui/views/toolbar_view.cc
index 3e62081..09c6d89 100644
--- a/chrome/browser/ui/views/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar_view.cc
@@ -254,6 +254,61 @@ void ToolbarView::RemoveMenuListener(views::MenuListener* listener) {
}
}
+SkBitmap ToolbarView::GetAppMenuIcon(views::CustomButton::ButtonState state) {
+ ui::ThemeProvider* tp = GetThemeProvider();
+
+ int id = 0;
+ switch (state) {
+ case views::CustomButton::BS_NORMAL: id = IDR_TOOLS; break;
+ case views::CustomButton::BS_HOT: id = IDR_TOOLS_H; break;
+ case views::CustomButton::BS_PUSHED: id = IDR_TOOLS_P; break;
+ default: NOTREACHED(); break;
+ }
+ SkBitmap icon = *tp->GetBitmapNamed(id);
+
+#if defined(OS_WIN)
+ // Keep track of whether we were showing the badge before, so we don't send
+ // multiple UMA events for example when multiple Chrome windows are open.
+ static bool incompatibility_badge_showing = false;
+ // Save the old value before resetting it.
+ bool was_showing = incompatibility_badge_showing;
+ incompatibility_badge_showing = false;
+#endif
+
+ bool add_badge = IsUpgradeRecommended() || ShouldShowIncompatibilityWarning();
+ if (!add_badge)
+ return icon;
+
+ // Draw the chrome app menu icon onto the canvas.
+ scoped_ptr<gfx::CanvasSkia> canvas(
+ new gfx::CanvasSkia(icon.width(), icon.height(), false));
+ canvas->DrawBitmapInt(icon, 0, 0);
+
+ SkBitmap badge;
+ // Only one badge can be active at any given time. The Upgrade notification
+ // is deemed most important, then the DLL conflict badge.
+ if (IsUpgradeRecommended()) {
+ badge = *tp->GetBitmapNamed(
+ UpgradeDetector::GetInstance()->GetIconResourceID(
+ UpgradeDetector::UPGRADE_ICON_TYPE_BADGE));
+ } else if (ShouldShowIncompatibilityWarning()) {
+#if defined(OS_WIN)
+ if (!was_showing)
+ UserMetrics::RecordAction(UserMetricsAction("ConflictBadge"));
+ badge = *tp->GetBitmapNamed(IDR_CONFLICT_BADGE);
+ incompatibility_badge_showing = true;
+#else
+ NOTREACHED();
+#endif
+ } else {
+ NOTREACHED();
+ }
+
+ canvas->DrawBitmapInt(badge, icon.width() - badge.width(), kBadgeTopMargin);
+
+ return canvas->ExtractBitmap();
+}
+
////////////////////////////////////////////////////////////////////////////////
// ToolbarView, AccessiblePaneView overrides:
@@ -655,58 +710,3 @@ void ToolbarView::UpdateAppMenuBadge() {
app_menu_->SetPushedIcon(GetAppMenuIcon(views::CustomButton::BS_PUSHED));
SchedulePaint();
}
-
-SkBitmap ToolbarView::GetAppMenuIcon(views::CustomButton::ButtonState state) {
- ui::ThemeProvider* tp = GetThemeProvider();
-
- int id = 0;
- switch (state) {
- case views::CustomButton::BS_NORMAL: id = IDR_TOOLS; break;
- case views::CustomButton::BS_HOT: id = IDR_TOOLS_H; break;
- case views::CustomButton::BS_PUSHED: id = IDR_TOOLS_P; break;
- default: NOTREACHED(); break;
- }
- SkBitmap icon = *tp->GetBitmapNamed(id);
-
-#if defined(OS_WIN)
- // Keep track of whether we were showing the badge before, so we don't send
- // multiple UMA events for example when multiple Chrome windows are open.
- static bool incompatibility_badge_showing = false;
- // Save the old value before resetting it.
- bool was_showing = incompatibility_badge_showing;
- incompatibility_badge_showing = false;
-#endif
-
- bool add_badge = IsUpgradeRecommended() || ShouldShowIncompatibilityWarning();
- if (!add_badge)
- return icon;
-
- // Draw the chrome app menu icon onto the canvas.
- scoped_ptr<gfx::CanvasSkia> canvas(
- new gfx::CanvasSkia(icon.width(), icon.height(), false));
- canvas->DrawBitmapInt(icon, 0, 0);
-
- SkBitmap badge;
- // Only one badge can be active at any given time. The Upgrade notification
- // is deemed most important, then the DLL conflict badge.
- if (IsUpgradeRecommended()) {
- badge = *tp->GetBitmapNamed(
- UpgradeDetector::GetInstance()->GetIconResourceID(
- UpgradeDetector::UPGRADE_ICON_TYPE_BADGE));
- } else if (ShouldShowIncompatibilityWarning()) {
-#if defined(OS_WIN)
- if (!was_showing)
- UserMetrics::RecordAction(UserMetricsAction("ConflictBadge"));
- badge = *tp->GetBitmapNamed(IDR_CONFLICT_BADGE);
- incompatibility_badge_showing = true;
-#else
- NOTREACHED();
-#endif
- } else {
- NOTREACHED();
- }
-
- canvas->DrawBitmapInt(badge, icon.width() - badge.width(), kBadgeTopMargin);
-
- return canvas->ExtractBitmap();
-}
diff --git a/chrome/browser/ui/views/toolbar_view.h b/chrome/browser/ui/views/toolbar_view.h
index 1a0dc8d..04a0a04 100644
--- a/chrome/browser/ui/views/toolbar_view.h
+++ b/chrome/browser/ui/views/toolbar_view.h
@@ -79,6 +79,10 @@ class ToolbarView : public AccessiblePaneView,
// Remove a menu listener.
void RemoveMenuListener(views::MenuListener* listener);
+ // Gets a bitmap with the icon for the app menu and any overlaid notification
+ // badge.
+ SkBitmap GetAppMenuIcon(views::CustomButton::ButtonState state);
+
virtual bool GetAcceleratorInfo(int id, ui::Accelerator* accel);
// Accessors...
@@ -170,10 +174,6 @@ class ToolbarView : public AccessiblePaneView,
// Updates the badge on the app menu (Wrench).
void UpdateAppMenuBadge();
- // Gets a bitmap with the icon for the app menu and any overlaid notification
- // badge.
- SkBitmap GetAppMenuIcon(views::CustomButton::ButtonState state);
-
// Gets a badge for the wrench icon corresponding to the number of
// unacknowledged background pages in the system.
SkBitmap GetBackgroundPageBadge();
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index dec0729..e459178 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2913,6 +2913,14 @@
'browser/ui/views/chrome_views_delegate.h',
'browser/ui/views/collected_cookies_win.cc',
'browser/ui/views/collected_cookies_win.h',
+ 'browser/ui/views/compact_nav/compact_location_bar_view.cc',
+ 'browser/ui/views/compact_nav/compact_location_bar_view.h',
+ 'browser/ui/views/compact_nav/compact_location_bar_view_host.cc',
+ 'browser/ui/views/compact_nav/compact_location_bar_view_host.h',
+ 'browser/ui/views/compact_nav/compact_navigation_bar.cc',
+ 'browser/ui/views/compact_nav/compact_navigation_bar.h',
+ 'browser/ui/views/compact_nav/compact_options_bar.cc',
+ 'browser/ui/views/compact_nav/compact_options_bar.h',
'browser/ui/views/constrained_html_delegate_gtk.cc',
'browser/ui/views/constrained_html_delegate_win.cc',
'browser/ui/views/constrained_window_views.cc',
@@ -2943,8 +2951,10 @@
'browser/ui/views/download/download_started_animation_win.cc',
'browser/ui/views/dropdown_bar_host.cc',
'browser/ui/views/dropdown_bar_host.h',
+ 'browser/ui/views/dropdown_bar_host_delegate.h',
'browser/ui/views/dropdown_bar_host_gtk.cc',
'browser/ui/views/dropdown_bar_host_win.cc',
+ 'browser/ui/views/dropdown_bar_view.cc',
'browser/ui/views/dropdown_bar_view.h',
'browser/ui/views/edit_search_engine_dialog.cc',
'browser/ui/views/edit_search_engine_dialog.h',
@@ -3987,6 +3997,14 @@
['include', '^browser/ui/views/bubble/bubble_border.cc'],
['include', '^browser/ui/views/bubble/bubble_border.h'],
['include', '^browser/ui/views/chrome_views_delegate.cc'],
+ ['include', '^browser/ui/views/compact_nav/compact_location_bar_view.cc'],
+ ['include', '^browser/ui/views/compact_nav/compact_location_bar_view.h'],
+ ['include', '^browser/ui/views/compact_nav/compact_location_bar_view_host.cc'],
+ ['include', '^browser/ui/views/compact_nav/compact_location_bar_view_host.h'],
+ ['include', '^browser/ui/views/compact_nav/compact_navigation_bar.cc'],
+ ['include', '^browser/ui/views/compact_nav/compact_navigation_bar.h'],
+ ['include', '^browser/ui/views/compact_nav/compact_options_bar.cc'],
+ ['include', '^browser/ui/views/compact_nav/compact_options_bar.h'],
['include', '^browser/ui/views/constrained_html_delegate_gtk.cc'],
['include', '^browser/ui/views/content_setting_bubble_contents.cc'],
['include', '^browser/ui/views/content_setting_bubble_contents.h'],
@@ -4008,6 +4026,7 @@
['include', '^browser/ui/views/dropdown_bar_host.cc'],
['include', '^browser/ui/views/dropdown_bar_host.h'],
['include', '^browser/ui/views/dropdown_bar_host_gtk.cc'],
+ ['include', '^browser/ui/views/dropdown_bar_view.cc'],
['include', '^browser/ui/views/dropdown_bar_view.h'],
['include', '^browser/ui/views/event_utils.cc'],
['include', '^browser/ui/views/event_utils.h'],
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 6325a44..0d0ec20 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -384,6 +384,10 @@ const char kEnableCloudPrintProxy[] = "enable-cloud-print-proxy";
// Enables the Cloud Print dialog hosting code.
const char kEnableCloudPrint[] = "enable-cloud-print";
+// Enables compact navigation mode, which removes the toolbar and moves most of
+// UI to the tab strip.
+const char kEnableCompactNavigation[] = "enable-compact-navigation";
+
// Enables compositing to texture instead of display.
const char kEnableCompositeToTexture[] = "enable-composite-to-texture";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index e720ac1..625864f 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -117,6 +117,7 @@ extern const char kEnableClearServerData[];
extern const char kEnableClickToPlay[];
extern const char kEnableCloudPrintProxy[];
extern const char kEnableCloudPrint[];
+extern const char kEnableCompactNavigation[];
extern const char kEnableCompositeToTexture[];
extern const char kEnableConnectBackupJobs[];
extern const char kEnableCrxlessWebApps[];
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index baf048d..603ccf6 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -685,6 +685,9 @@ const char kEditBookmarksEnabled[] = "bookmarks.editing_enabled";
// side of the browser window.
const char kUseVerticalTabs[] = "tabs.use_vertical_tabs";
+// Boolean that is true when the compact navigation bar is to be used.
+const char kUseCompactNavigationBar[] = "tabs.use_compact_navigation_bar";
+
// Boolean that is true when the translate feature is enabled.
const char kEnableTranslate[] = "translate.enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index bae339b..b2f4841 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -240,6 +240,7 @@ extern const char kAutofillPersonalDataManagerFirstRun[];
extern const char kEditBookmarksEnabled[];
extern const char kUseVerticalTabs[];
+extern const char kUseCompactNavigationBar[];
extern const char kEnableTranslate[];
extern const char kEnableBookmarkBar[];
extern const char kPinnedTabs[];
diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h
index 9048c40..7116897 100644
--- a/chrome/test/test_browser_window.h
+++ b/chrome/test/test_browser_window.h
@@ -59,9 +59,7 @@ class TestBrowserWindow : public BrowserWindow {
TabContentsWrapper* tab_contents) {}
virtual void ShowCreateChromeAppShortcutsDialog(Profile* profile,
const Extension* app) {}
-#if defined(TOOLKIT_VIEWS)
- virtual void ToggleCompactNavigationBar() {}
-#endif // defined(TOOLKIT_VIEWS)
+ virtual void ToggleUseCompactNavigationBar() {}
virtual bool IsBookmarkBarVisible() const;
virtual bool IsBookmarkBarAnimating() const;
diff --git a/views/events/event.h b/views/events/event.h
index 5ede973..924a350 100644
--- a/views/events/event.h
+++ b/views/events/event.h
@@ -27,6 +27,11 @@ namespace views {
class RootView;
class View;
+#if defined(OS_WIN)
+bool IsClientMouseEvent(const views::NativeEvent& native_event);
+bool IsNonClientMouseEvent(const views::NativeEvent& native_event);
+#endif
+
////////////////////////////////////////////////////////////////////////////////
//
// Event class
diff --git a/views/events/event_win.cc b/views/events/event_win.cc
index 06c892c..9e063d3 100644
--- a/views/events/event_win.cc
+++ b/views/events/event_win.cc
@@ -74,20 +74,6 @@ ui::EventType EventTypeFromNative(NativeEvent native_event) {
return ui::ET_UNKNOWN;
}
-bool IsClientMouseEvent(NativeEvent native_event) {
- return native_event.message == WM_MOUSELEAVE ||
- native_event.message == WM_MOUSEHOVER ||
- (native_event.message >= WM_MOUSEFIRST &&
- native_event.message <= WM_MOUSELAST);
-}
-
-bool IsNonClientMouseEvent(NativeEvent native_event) {
- return native_event.message == WM_NCMOUSELEAVE ||
- native_event.message == WM_NCMOUSEHOVER ||
- (native_event.message >= WM_NCMOUSEMOVE &&
- native_event.message <= WM_NCXBUTTONDBLCLK);
-}
-
// Get views::Event flags from a native Windows message
int EventFlagsFromNative(NativeEvent native_event) {
int flags = 0;
@@ -172,6 +158,20 @@ int EventFlagsFromNative(NativeEvent native_event) {
} // namespace
+bool IsClientMouseEvent(const views::NativeEvent& native_event) {
+ return native_event.message == WM_MOUSELEAVE ||
+ native_event.message == WM_MOUSEHOVER ||
+ (native_event.message >= WM_MOUSEFIRST &&
+ native_event.message <= WM_MOUSELAST);
+}
+
+bool IsNonClientMouseEvent(const views::NativeEvent& native_event) {
+ return native_event.message == WM_NCMOUSELEAVE ||
+ native_event.message == WM_NCMOUSEHOVER ||
+ (native_event.message >= WM_NCMOUSEMOVE &&
+ native_event.message <= WM_NCXBUTTONDBLCLK);
+}
+
////////////////////////////////////////////////////////////////////////////////
// Event, public: