summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 03:20:27 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 03:20:27 +0000
commitad3d7273dff93e5107a947c05c6a47c35ea7eea7 (patch)
treedd34fa6e3aaa7080885f5d28e046c76751f7d25f
parent21bd81995a2dbeb92833ee6b55612ec30ce6122f (diff)
downloadchromium_src-ad3d7273dff93e5107a947c05c6a47c35ea7eea7.zip
chromium_src-ad3d7273dff93e5107a947c05c6a47c35ea7eea7.tar.gz
chromium_src-ad3d7273dff93e5107a947c05c6a47c35ea7eea7.tar.bz2
Relands your patch to have an option for enabling vertical tabs. I've
added the following additions: . made the layout work for opaque_browser_frame. . Only show the menu if the user supplied --enable-vertical-tabs. BUG=none TEST=none Review URL: http://codereview.chromium.org/1708014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45906 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/browser.cc26
-rw-r--r--chrome/browser/browser.h5
-rw-r--r--chrome/browser/browser_window.h3
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.h1
-rw-r--r--chrome/browser/cocoa/tab_strip_controller_unittest.mm4
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h1
-rw-r--r--chrome/browser/tab_menu_model.cc17
-rw-r--r--chrome/browser/tab_menu_model.h3
-rw-r--r--chrome/browser/tabs/tab_strip_model.cc25
-rw-r--r--chrome/browser/tabs/tab_strip_model.h11
-rw-r--r--chrome/browser/tabs/tab_strip_model_unittest.cc2
-rw-r--r--chrome/browser/views/frame/browser_frame.h8
-rw-r--r--chrome/browser/views/frame/browser_frame_gtk.cc7
-rw-r--r--chrome/browser/views/frame/browser_frame_gtk.h2
-rw-r--r--chrome/browser/views/frame/browser_frame_win.cc13
-rw-r--r--chrome/browser/views/frame/browser_frame_win.h2
-rw-r--r--chrome/browser/views/frame/browser_view.cc47
-rw-r--r--chrome/browser/views/frame/browser_view.h10
-rw-r--r--chrome/browser/views/frame/browser_view_layout.cc14
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.cc12
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.cc17
-rw-r--r--chrome/browser/views/tabs/browser_tab_strip_controller.cc107
-rw-r--r--chrome/browser/views/tabs/browser_tab_strip_controller.h17
-rw-r--r--chrome/browser/views/tabs/side_tab.cc26
-rw-r--r--chrome/browser/views/tabs/side_tab.h9
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.cc22
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.h9
-rw-r--r--chrome/browser/views/tabs/side_tab_strip_model.h9
-rw-r--r--chrome/browser/views/tabs/tab.cc4
-rw-r--r--chrome/browser/views/tabs/tab.h4
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc20
-rw-r--r--chrome/browser/views/tabs/tab_strip.h7
-rw-r--r--chrome/common/notification_type.h3
-rw-r--r--chrome/test/test_browser_window.h1
35 files changed, 389 insertions, 85 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 401ddde..1ebb1a3 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4602,6 +4602,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_TAB_CXMENU_BOOKMARK_ALL_TABS" desc="In Title Case: The label of the tab context menu item for creating a bookmark folder containing an entry for each open tab.">
Bookmark all tabs...
</message>
+ <message name="IDS_TAB_CXMENU_USE_VERTICAL_TABS" desc="Use the vertical tab strip">
+ Use side tabs
+ </message>
</if>
<if expr="pp_ifdef('use_titlecase')">
<message name="IDS_TAB_CXMENU_NEWTAB" desc="In Title Case: The label of the 'New Tab' Tab context menu item.">
@@ -4634,6 +4637,9 @@ Keep your key file in a safe place. You will need it to create new versions of y
<message name="IDS_TAB_CXMENU_BOOKMARK_ALL_TABS" desc="In Title Case: The label of the tab context menu item for creating a bookmark folder containing an entry for each open tab.">
Bookmark All Tabs...
</message>
+ <message name="IDS_TAB_CXMENU_USE_VERTICAL_TABS" desc="Use the vertical tab strip">
+ Use Side Tabs
+ </message>
</if>
<!-- Bookmarks bar -->
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index efb6f1a..f810c7e 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -67,6 +67,7 @@
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/tab_menu_model.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/window_sizer.h"
#include "chrome/common/chrome_constants.h"
@@ -195,6 +196,12 @@ Browser::Browser(Type type, Profile* profile)
encoding_auto_detect_.Init(prefs::kWebKitUsesUniversalDetector,
profile_->GetPrefs(), NULL);
+ use_vertical_tabs_.Init(prefs::kUseVerticalTabs, 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);
+ }
}
Browser::~Browser() {
@@ -1667,7 +1674,7 @@ void Browser::RegisterUserPrefs(PrefService* prefs) {
prefs->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop, true);
prefs->RegisterBooleanPref(prefs::kWebAppCreateInAppsMenu, true);
prefs->RegisterBooleanPref(prefs::kWebAppCreateInQuickLaunchBar, true);
- prefs->RegisterBooleanPref(prefs::kUseVerticalTabs, true);
+ prefs->RegisterBooleanPref(prefs::kUseVerticalTabs, false);
prefs->RegisterBooleanPref(prefs::kEnableTranslate, true);
}
@@ -2096,6 +2103,15 @@ void Browser::BookmarkAllTabs() {
BookmarkEditor::SHOW_TREE);
}
+bool Browser::UseVerticalTabs() const {
+ return use_vertical_tabs_.GetValue();
+}
+
+void Browser::ToggleUseVerticalTabs() {
+ use_vertical_tabs_.SetValue(!UseVerticalTabs());
+ window()->ToggleTabStripMode();
+}
+
///////////////////////////////////////////////////////////////////////////////
// Browser, TabStripModelObserver implementation:
@@ -2752,6 +2768,14 @@ void Browser::Observe(NotificationType type,
break;
}
+ case NotificationType::PREF_CHANGED: {
+ if (*(Details<std::wstring>(details).ptr()) == prefs::kUseVerticalTabs)
+ window()->ToggleTabStripMode();
+ else
+ NOTREACHED();
+ break;
+ }
+
default:
NOTREACHED() << "Got a notification we didn't register for.";
}
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index 15123da..6527d2c 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -622,6 +622,8 @@ class Browser : public TabStripModelDelegate,
virtual bool CanCloseContentsAt(int index);
virtual bool CanBookmarkAllTabs() const;
virtual void BookmarkAllTabs();
+ virtual bool UseVerticalTabs() const;
+ virtual void ToggleUseVerticalTabs();
// Overridden from TabStripModelObserver:
virtual void TabInsertedAt(TabContents* contents,
@@ -968,6 +970,9 @@ class Browser : public TabStripModelDelegate,
// The extension app associated with this window, if any.
Extension* extension_app_;
+ // Tracks the display mode of the tabstrip.
+ mutable BooleanPrefMember use_vertical_tabs_;
+
DISALLOW_COPY_AND_ASSIGN(Browser);
};
diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h
index 4d2b461..fa7b22b 100644
--- a/chrome/browser/browser_window.h
+++ b/chrome/browser/browser_window.h
@@ -304,6 +304,9 @@ class BrowserWindow {
virtual void Copy() = 0;
virtual void Paste() = 0;
+ // Switches between available tabstrip display modes.
+ virtual void ToggleTabStripMode() = 0;
+
// Construct a BrowserWindow implementation for the specified |browser|.
static BrowserWindow* CreateBrowserWindow(Browser* browser);
diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h
index b79712a..dc760f8 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/cocoa/browser_window_cocoa.h
@@ -102,6 +102,7 @@ class BrowserWindowCocoa : public BrowserWindow,
virtual void Cut();
virtual void Copy();
virtual void Paste();
+ virtual void ToggleTabStripMode() {}
// Overridden from NotificationObserver
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/cocoa/tab_strip_controller_unittest.mm b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
index 82cea8e..2a161ab 100644
--- a/chrome/browser/cocoa/tab_strip_controller_unittest.mm
+++ b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
@@ -63,6 +63,10 @@ class TestTabStripDelegate : public TabStripModelDelegate {
virtual bool CanBookmarkAllTabs() const { return false; }
virtual void BookmarkAllTabs() {}
+
+ virtual bool UseVerticalTabs() const { return false; }
+
+ virtual void ToggleUseVerticalTabs() {}
};
class TabStripControllerTest : public CocoaTest {
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index 3f10f57..d193d13 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -120,6 +120,7 @@ class BrowserWindowGtk : public BrowserWindow,
virtual void Cut();
virtual void Copy();
virtual void Paste();
+ virtual void ToggleTabStripMode() {}
// Overridden from NotificationObserver:
virtual void Observe(NotificationType type,
diff --git a/chrome/browser/tab_menu_model.cc b/chrome/browser/tab_menu_model.cc
index bb0ba34..f955837 100644
--- a/chrome/browser/tab_menu_model.cc
+++ b/chrome/browser/tab_menu_model.cc
@@ -4,7 +4,9 @@
#include "chrome/browser/tab_menu_model.h"
+#include "base/command_line.h"
#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/common/chrome_switches.h"
#include "grit/generated_resources.h"
TabMenuModel::TabMenuModel(menus::SimpleMenuModel::Delegate* delegate,
@@ -13,6 +15,16 @@ TabMenuModel::TabMenuModel(menus::SimpleMenuModel::Delegate* delegate,
Build(is_pinned);
}
+// static
+bool TabMenuModel::AreVerticalTabsEnabled() {
+#if defined(TOOLKIT_VIEWS)
+ return CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableVerticalTabs);
+#else
+ return false;
+#endif
+}
+
void TabMenuModel::Build(bool is_pinned) {
AddItemWithStringId(TabStripModel::CommandNewTab, IDS_TAB_CXMENU_NEWTAB);
AddSeparator();
@@ -35,4 +47,9 @@ void TabMenuModel::Build(bool is_pinned) {
AddItemWithStringId(TabStripModel::CommandRestoreTab, IDS_RESTORE_TAB);
AddItemWithStringId(TabStripModel::CommandBookmarkAllTabs,
IDS_TAB_CXMENU_BOOKMARK_ALL_TABS);
+ if (AreVerticalTabsEnabled()) {
+ AddSeparator();
+ AddCheckItemWithStringId(TabStripModel::CommandUseVerticalTabs,
+ IDS_TAB_CXMENU_USE_VERTICAL_TABS);
+ }
}
diff --git a/chrome/browser/tab_menu_model.h b/chrome/browser/tab_menu_model.h
index dca49af..189fefe 100644
--- a/chrome/browser/tab_menu_model.h
+++ b/chrome/browser/tab_menu_model.h
@@ -18,6 +18,9 @@ class TabMenuModel : public menus::SimpleMenuModel {
TabMenuModel(menus::SimpleMenuModel::Delegate* delegate, bool is_pinned);
virtual ~TabMenuModel() {}
+ // Returns true if vertical tabs are enabled.
+ static bool AreVerticalTabsEnabled();
+
private:
void Build(bool is_pinned);
diff --git a/chrome/browser/tabs/tab_strip_model.cc b/chrome/browser/tabs/tab_strip_model.cc
index b5095a2..a1b1355 100644
--- a/chrome/browser/tabs/tab_strip_model.cc
+++ b/chrome/browser/tabs/tab_strip_model.cc
@@ -574,11 +574,24 @@ bool TabStripModel::IsContextMenuCommandEnabled(
return delegate_->CanRestoreTab();
case CommandTogglePinned:
return true;
- case CommandBookmarkAllTabs: {
+ case CommandBookmarkAllTabs:
return delegate_->CanBookmarkAllTabs();
- }
+ case CommandUseVerticalTabs:
+ return true;
+ default:
+ NOTREACHED();
+ }
+ return false;
+}
+
+bool TabStripModel::IsContextMenuCommandChecked(int context_index,
+ ContextMenuCommand command_id) const {
+ switch (command_id) {
+ case CommandUseVerticalTabs:
+ return delegate()->UseVerticalTabs();
default:
NOTREACHED();
+ break;
}
return false;
}
@@ -655,6 +668,14 @@ void TabStripModel::ExecuteContextMenuCommand(
delegate_->BookmarkAllTabs();
break;
}
+ case CommandUseVerticalTabs: {
+ UserMetrics::RecordAction(
+ UserMetricsAction("TabContextMenu_UseVerticalTabs"),
+ profile_);
+
+ delegate()->ToggleUseVerticalTabs();
+ break;
+ }
default:
NOTREACHED();
}
diff --git a/chrome/browser/tabs/tab_strip_model.h b/chrome/browser/tabs/tab_strip_model.h
index 427fb6e..90b4419 100644
--- a/chrome/browser/tabs/tab_strip_model.h
+++ b/chrome/browser/tabs/tab_strip_model.h
@@ -223,6 +223,12 @@ class TabStripModelDelegate {
// Creates a bookmark folder containing a bookmark for all open tabs.
virtual void BookmarkAllTabs() = 0;
+
+ // Returns true if the vertical tabstrip presentation should be used.
+ virtual bool UseVerticalTabs() const = 0;
+
+ // Toggles the use of the vertical tabstrip.
+ virtual void ToggleUseVerticalTabs() = 0;
};
////////////////////////////////////////////////////////////////////////////////
@@ -547,6 +553,7 @@ class TabStripModel : public NotificationObserver {
CommandRestoreTab,
CommandTogglePinned,
CommandBookmarkAllTabs,
+ CommandUseVerticalTabs,
CommandLast
};
@@ -554,6 +561,10 @@ class TabStripModel : public NotificationObserver {
bool IsContextMenuCommandEnabled(int context_index,
ContextMenuCommand command_id) const;
+ // Returns true if the specified command is checked.
+ bool IsContextMenuCommandChecked(int context_index,
+ ContextMenuCommand command_id) const;
+
// Performs the action associated with the specified command for the given
// TabStripModel index |context_index|.
void ExecuteContextMenuCommand(int context_index,
diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc
index 451cc81..44c56e6 100644
--- a/chrome/browser/tabs/tab_strip_model_unittest.cc
+++ b/chrome/browser/tabs/tab_strip_model_unittest.cc
@@ -71,6 +71,8 @@ class TabStripDummyDelegate : public TabStripModelDelegate {
virtual bool CanCloseContentsAt(int index) { return can_close_ ; }
virtual bool CanBookmarkAllTabs() const { return false; }
virtual void BookmarkAllTabs() {}
+ virtual bool UseVerticalTabs() const { return false; }
+ virtual void ToggleUseVerticalTabs() {}
private:
// A dummy TabContents we give to callers that expect us to actually build a
diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h
index fd94d51..392200d 100644
--- a/chrome/browser/views/frame/browser_frame.h
+++ b/chrome/browser/views/frame/browser_frame.h
@@ -41,10 +41,6 @@ class BrowserFrame {
// construction.
virtual views::Window* GetWindow() = 0;
- // Notification that the tab strip has been created. This should let the
- // BrowserRootView know about it so it can enable drag and drop.
- virtual void TabStripCreated(BaseTabStrip* tabstrip) = 0;
-
// Determine the distance of the left edge of the minimize button from the
// left edge of the window. Used in our Non-Client View's Layout.
virtual int GetMinimizeButtonOffset() const = 0;
@@ -74,6 +70,10 @@ class BrowserFrame {
// calls this method _after_ the TabStrip has painted itself so the shadow is
// rendered above the tabs.
virtual void PaintTabStripShadow(gfx::Canvas* canvas) = 0;
+
+ // Notifies the frame that the tab strip display mode changed so it can update
+ // its frame treatment if necessary.
+ virtual void TabStripDisplayModeChanged() = 0;
};
#endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_FRAME_H_
diff --git a/chrome/browser/views/frame/browser_frame_gtk.cc b/chrome/browser/views/frame/browser_frame_gtk.cc
index ef6f5a1..cb67b3b 100644
--- a/chrome/browser/views/frame/browser_frame_gtk.cc
+++ b/chrome/browser/views/frame/browser_frame_gtk.cc
@@ -102,9 +102,6 @@ views::Window* BrowserFrameGtk::GetWindow() {
return this;
}
-void BrowserFrameGtk::TabStripCreated(BaseTabStrip* tabstrip) {
-}
-
int BrowserFrameGtk::GetMinimizeButtonOffset() const {
NOTIMPLEMENTED();
return 0;
@@ -139,6 +136,10 @@ views::View* BrowserFrameGtk::GetFrameView() const {
void BrowserFrameGtk::PaintTabStripShadow(gfx::Canvas* canvas) {
}
+void BrowserFrameGtk::TabStripDisplayModeChanged() {
+ GetRootView()->Layout();
+}
+
ThemeProvider* BrowserFrameGtk::GetThemeProvider() const {
return profile_->GetThemeProvider();
}
diff --git a/chrome/browser/views/frame/browser_frame_gtk.h b/chrome/browser/views/frame/browser_frame_gtk.h
index 93330c1..f8e8f2a 100644
--- a/chrome/browser/views/frame/browser_frame_gtk.h
+++ b/chrome/browser/views/frame/browser_frame_gtk.h
@@ -28,7 +28,6 @@ class BrowserFrameGtk : public BrowserFrame,
// Overridden from BrowserFrame:
virtual views::Window* GetWindow();
- virtual void TabStripCreated(BaseTabStrip* tabstrip);
virtual int GetMinimizeButtonOffset() const;
virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const;
virtual void UpdateThrobber(bool running);
@@ -37,6 +36,7 @@ class BrowserFrameGtk : public BrowserFrame,
virtual bool AlwaysUseNativeFrame() const;
virtual views::View* GetFrameView() const;
virtual void PaintTabStripShadow(gfx::Canvas* canvas);
+ virtual void TabStripDisplayModeChanged();
// Overridden from views::Widget:
virtual ThemeProvider* GetThemeProvider() const;
diff --git a/chrome/browser/views/frame/browser_frame_win.cc b/chrome/browser/views/frame/browser_frame_win.cc
index 7239b53..e0b420e 100644
--- a/chrome/browser/views/frame/browser_frame_win.cc
+++ b/chrome/browser/views/frame/browser_frame_win.cc
@@ -72,9 +72,6 @@ views::Window* BrowserFrameWin::GetWindow() {
return this;
}
-void BrowserFrameWin::TabStripCreated(BaseTabStrip* tabstrip) {
-}
-
int BrowserFrameWin::GetMinimizeButtonOffset() const {
TITLEBARINFOEX titlebar_info;
titlebar_info.cbSize = sizeof(TITLEBARINFOEX);
@@ -133,6 +130,12 @@ void BrowserFrameWin::PaintTabStripShadow(gfx::Canvas* canvas) {
browser_frame_view_->PaintTabStripShadow(canvas);
}
+void BrowserFrameWin::TabStripDisplayModeChanged() {
+ GetRootView()->Layout();
+ UpdateDWMFrame();
+ GetRootView()->Layout();
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserFrame, views::WindowWin overrides:
@@ -303,7 +306,7 @@ void BrowserFrameWin::UpdateDWMFrame() {
// In maximized mode, we only have a titlebar strip of glass, no side/bottom
// borders.
if (!browser_view_->IsFullscreen()) {
- if (browser_view_->UsingSideTabs()) {
+ if (browser_view_->UseVerticalTabs()) {
margins.cxLeftWidth +=
GetBoundsForTabStrip(browser_view_->tabstrip()).right();
margins.cyTopHeight += GetSystemMetrics(SM_CYSIZEFRAME);
@@ -319,7 +322,7 @@ void BrowserFrameWin::UpdateDWMFrame() {
DwmExtendFrameIntoClientArea(GetNativeView(), &margins);
DWORD window_style = GetWindowLong(GWL_STYLE);
- if (browser_view_->UsingSideTabs()) {
+ if (browser_view_->UseVerticalTabs()) {
if (window_style & WS_CAPTION)
SetWindowLong(GWL_STYLE, window_style & ~WS_CAPTION);
} else {
diff --git a/chrome/browser/views/frame/browser_frame_win.h b/chrome/browser/views/frame/browser_frame_win.h
index d928f93..42e8974 100644
--- a/chrome/browser/views/frame/browser_frame_win.h
+++ b/chrome/browser/views/frame/browser_frame_win.h
@@ -37,7 +37,6 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin {
// BrowserFrame implementation.
virtual views::Window* GetWindow();
- virtual void TabStripCreated(BaseTabStrip* tabstrip);
virtual int GetMinimizeButtonOffset() const;
virtual gfx::Rect GetBoundsForTabStrip(BaseTabStrip* tabstrip) const;
virtual void UpdateThrobber(bool running);
@@ -46,6 +45,7 @@ class BrowserFrameWin : public BrowserFrame, public views::WindowWin {
virtual bool AlwaysUseNativeFrame() const;
virtual views::View* GetFrameView() const;
virtual void PaintTabStripShadow(gfx::Canvas* canvas);
+ virtual void TabStripDisplayModeChanged();
protected:
// Overridden from views::WindowWin:
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index e8ee1d9..70fcc10 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -530,8 +530,8 @@ bool BrowserView::IsTabStripVisible() const {
return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
}
-bool BrowserView::UsingSideTabs() const {
- return SideTabStrip::Visible(browser_->profile());
+bool BrowserView::UseVerticalTabs() const {
+ return browser_->tabstrip_model()->delegate()->UseVerticalTabs();
}
bool BrowserView::IsOffTheRecord() const {
@@ -1206,6 +1206,11 @@ void BrowserView::Paste() {
false, false);
}
+void BrowserView::ToggleTabStripMode() {
+ InitTabStrip(browser_->tabstrip_model());
+ frame_->TabStripDisplayModeChanged();
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserView, BrowserWindowTesting implementation:
@@ -1609,13 +1614,34 @@ views::LayoutManager* BrowserView::CreateLayoutManager() const {
return new BrowserViewLayout;
}
-BaseTabStrip* BrowserView::CreateTabStrip(TabStripModel* model) {
- if (UsingSideTabs()) {
+void BrowserView::InitTabStrip(TabStripModel* model) {
+// Throw away the existing tabstrip if we're switching display modes.
+ if (tabstrip_) {
+ tabstrip_->GetParent()->RemoveChildView(tabstrip_);
+ delete tabstrip_;
+ }
+
+ TabStrip* tabstrip_as_tabstrip = NULL;
+ BrowserTabStripController* tabstrip_controller = NULL;
+
+ if (UseVerticalTabs()) {
SideTabStrip* tabstrip = new SideTabStrip;
- tabstrip->SetModel(new BrowserTabStripController(model, tabstrip));
- return tabstrip;
+ tabstrip_controller = new BrowserTabStripController(model, tabstrip);
+ tabstrip->SetModel(tabstrip_controller);
+ tabstrip_ = tabstrip;
+ } else {
+ tabstrip_as_tabstrip = new TabStrip(model);
+ tabstrip_ = tabstrip_as_tabstrip;
}
- return new TabStrip(model);
+ tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP));
+ if (browser_->extension_app() && tabstrip_->AsTabStrip())
+ tabstrip_->AsTabStrip()->set_new_tab_button_enabled(false);
+ AddChildView(tabstrip_);
+
+ if (tabstrip_controller)
+ tabstrip_controller->InitFromModel();
+ else
+ tabstrip_as_tabstrip->InitFromModel();
}
///////////////////////////////////////////////////////////////////////////////
@@ -1674,12 +1700,7 @@ void BrowserView::Init() {
}
}
- tabstrip_ = CreateTabStrip(browser_->tabstrip_model());
- tabstrip_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_TABSTRIP));
- if (browser_->extension_app() && tabstrip_->AsTabStrip())
- tabstrip_->AsTabStrip()->set_new_tab_button_enabled(false);
- AddChildView(tabstrip_);
- frame_->TabStripCreated(tabstrip_);
+ InitTabStrip(browser_->tabstrip_model());
toolbar_ = new ToolbarView(browser_.get());
AddChildView(toolbar_);
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index 7e52404..4e13040 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -167,7 +167,7 @@ class BrowserView : public BrowserBubbleHost,
bool IsTabStripVisible() const;
// Returns true if the vertical tabstrip is in use.
- bool UsingSideTabs() const;
+ bool UseVerticalTabs() const;
// Returns true if the profile associated with this Browser window is
// off the record.
@@ -336,6 +336,7 @@ class BrowserView : public BrowserBubbleHost,
virtual void Cut();
virtual void Copy();
virtual void Paste();
+ virtual void ToggleTabStripMode();
// Overridden from BrowserWindowTesting:
virtual BookmarkBarView* GetBookmarkBarView() const;
@@ -409,9 +410,10 @@ class BrowserView : public BrowserBubbleHost,
// override to implemnet different layout pocily.
virtual views::LayoutManager* CreateLayoutManager() const;
- // Returns a new TabStrip for the browser view. A subclass may
- // override to return a different TabStrip implementation.
- virtual BaseTabStrip* CreateTabStrip(TabStripModel* tab_strip_model);
+ // Initializes a new TabStrip for the browser view. This can be performed
+ // multiple times over the life of the browser, and is run when the display
+ // mode for the tabstrip changes from horizontal to vertical.
+ void InitTabStrip(TabStripModel* tab_strip_model);
// Browser window related initializations.
virtual void Init();
diff --git a/chrome/browser/views/frame/browser_view_layout.cc b/chrome/browser/views/frame/browser_view_layout.cc
index 505a913..8f2588d 100644
--- a/chrome/browser/views/frame/browser_view_layout.cc
+++ b/chrome/browser/views/frame/browser_view_layout.cc
@@ -321,7 +321,7 @@ int BrowserViewLayout::LayoutTabStrip() {
gfx::Rect layout_bounds =
browser_view_->frame()->GetBoundsForTabStrip(tabstrip_);
- if (browser_view_->UsingSideTabs()) {
+ if (browser_view_->UseVerticalTabs()) {
vertical_layout_rect_.Inset(
layout_bounds.right() - kBrowserViewTabStripHorizontalOverlap, 0, 0, 0);
} else {
@@ -337,18 +337,18 @@ int BrowserViewLayout::LayoutTabStrip() {
layout_bounds.set_origin(tabstrip_origin);
tabstrip_->SetVisible(true);
tabstrip_->SetBounds(layout_bounds);
- return browser_view_->UsingSideTabs() ? 0 : layout_bounds.bottom();
+ return browser_view_->UseVerticalTabs() ?
+ layout_bounds.y() : layout_bounds.bottom();
}
int BrowserViewLayout::LayoutToolbar(int top) {
int browser_view_width = vertical_layout_rect_.width();
bool visible = browser_view_->IsToolbarVisible();
toolbar_->location_bar()->SetFocusable(visible);
- int y = 0;
- if (!browser_view_->UsingSideTabs()) {
- y = top -
- ((visible && browser_view_->IsTabStripVisible())
- ? kToolbarTabStripVerticalOverlap : 0);
+ int y = top;
+ if (!browser_view_->UseVerticalTabs()) {
+ y -= ((visible && browser_view_->IsTabStripVisible()) ?
+ kToolbarTabStripVerticalOverlap : 0);
}
int height = 0;
if (visible) {
diff --git a/chrome/browser/views/frame/glass_browser_frame_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc
index 9a665f7..0026e60 100644
--- a/chrome/browser/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/views/frame/glass_browser_frame_view.cc
@@ -77,7 +77,7 @@ GlassBrowserFrameView::~GlassBrowserFrameView() {
gfx::Rect GlassBrowserFrameView::GetBoundsForTabStrip(
BaseTabStrip* tabstrip) const {
- if (browser_view_->UsingSideTabs()) {
+ if (browser_view_->UseVerticalTabs()) {
gfx::Size ps = tabstrip->GetPreferredSize();
return gfx::Rect(0, NonClientTopBorderHeight(), ps.width(),
browser_view_->height());
@@ -114,8 +114,10 @@ void GlassBrowserFrameView::UpdateThrobber(bool running) {
}
void GlassBrowserFrameView::PaintTabStripShadow(gfx::Canvas* canvas) {
- if (!browser_view_->UILayoutIsRightToLeft())
+ if (!browser_view_->UILayoutIsRightToLeft() ||
+ !browser_view_->UseVerticalTabs()) {
return;
+ }
ThemeProvider* tp = GetThemeProvider();
SkBitmap* shadow_top = tp->GetBitmapNamed(IDR_SIDETABS_SHADOW_TOP);
@@ -237,7 +239,7 @@ int GlassBrowserFrameView::NonClientTopBorderHeight() const {
// We'd like to use FrameBorderThickness() here, but the maximized Aero glass
// frame has a 0 frame border around most edges and a CXSIZEFRAME-thick border
// at the top (see AeroGlassFrame::OnGetMinMaxInfo()).
- const int kRestoredHeight = browser_view_->UsingSideTabs() ?
+ const int kRestoredHeight = browser_view_->UseVerticalTabs() ?
-2 : kNonClientRestoredExtraThickness;
return GetSystemMetrics(SM_CXSIZEFRAME) + (browser_view_->IsMaximized() ?
-kTabstripTopShadowThickness : kRestoredHeight);
@@ -256,7 +258,7 @@ void GlassBrowserFrameView::PaintToolbarBackground(gfx::Canvas* canvas) {
// Draw the toolbar background, setting src_y of the paint to the tab
// strip height as the toolbar background begins at the top of the tabs.
- int src_y = browser_view_->UsingSideTabs()
+ int src_y = browser_view_->UseVerticalTabs()
? TabRenderer::GetMinimumUnselectedSize().height()
: browser_view_->GetTabStripHeight() - 1;
canvas->TileImageInt(*theme_toolbar, 0, src_y,
@@ -333,7 +335,7 @@ void GlassBrowserFrameView::PaintRestoredClientEdge(gfx::Canvas* canvas) {
tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height();
gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
- if (browser_view_->UsingSideTabs()) {
+ if (browser_view_->UseVerticalTabs()) {
client_area_bounds.Inset(
GetBoundsForTabStrip(browser_view_->tabstrip()).width() - 4, 0, 0, 0);
}
diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc
index 5014ef42..3b92e3b 100644
--- a/chrome/browser/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc
@@ -194,9 +194,14 @@ OpaqueBrowserFrameView::~OpaqueBrowserFrameView() {
gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip(
BaseTabStrip* tabstrip) const {
- int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ?
- (otr_avatar_icon_->bounds().right() + kOTRSideSpacing) :
- NonClientBorderThickness() + kTabStripIndent;
+ if (browser_view_->UseVerticalTabs()) {
+ // Position the tab strip slightly below the caption buttons.
+ // TODO(sky): adjust the 2.
+ int y = CaptionButtonY() + minimize_button_->GetPreferredSize().height() +
+ 2;
+ gfx::Size ps = tabstrip->GetPreferredSize();
+ return gfx::Rect(0, y, ps.width(), browser_view_->height());
+ }
int tabstrip_y = NonClientTopBorderHeight();
if (!frame_->GetWindow()->IsMaximized() &&
@@ -204,6 +209,10 @@ gfx::Rect OpaqueBrowserFrameView::GetBoundsForTabStrip(
tabstrip_y += kNonClientRestoredExtraThickness;
}
+ int tabstrip_x = browser_view_->ShouldShowOffTheRecordAvatar() ?
+ (otr_avatar_icon_->bounds().right() + kOTRSideSpacing) :
+ NonClientBorderThickness() + kTabStripIndent;
+
int tabstrip_width = minimize_button_->x() - tabstrip_x -
(frame_->GetWindow()->IsMaximized() ?
kNewTabCaptionMaximizedSpacing : kNewTabCaptionRestoredSpacing);
@@ -247,7 +256,7 @@ gfx::Size OpaqueBrowserFrameView::GetMinimumSize() {
}
void OpaqueBrowserFrameView::PaintTabStripShadow(gfx::Canvas* canvas) {
- // TODO(beng): SIDE tabs.
+ // TODO(sky): SIDE tabs.
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/views/tabs/browser_tab_strip_controller.cc
index 343ee09..e828326 100644
--- a/chrome/browser/views/tabs/browser_tab_strip_controller.cc
+++ b/chrome/browser/views/tabs/browser_tab_strip_controller.cc
@@ -5,7 +5,69 @@
#include "chrome/browser/views/tabs/browser_tab_strip_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_menu_model.h"
#include "chrome/browser/views/tabs/side_tab_strip.h"
+#include "views/controls/menu/menu_2.h"
+#include "views/widget/widget.h"
+
+class BrowserTabStripController::TabContextMenuContents
+ : public menus::SimpleMenuModel::Delegate {
+ public:
+ TabContextMenuContents(int tab_index, BrowserTabStripController* controller)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(
+ model_(this, controller->IsTabPinned(tab_index))),
+ tab_index_(tab_index),
+ controller_(controller) {
+ Build();
+ }
+ virtual ~TabContextMenuContents() {
+ menu_->CancelMenu();
+ }
+
+ void RunMenuAt(const gfx::Point& point) {
+ menu_->RunMenuAt(point, views::Menu2::ALIGN_TOPLEFT);
+ }
+
+ // Overridden from menus::SimpleMenuModel::Delegate:
+ virtual bool IsCommandIdChecked(int command_id) const {
+ return controller_->IsCommandCheckedForTab(
+ static_cast<TabStripModel::ContextMenuCommand>(command_id),
+ tab_index_);
+ }
+ virtual bool IsCommandIdEnabled(int command_id) const {
+ return controller_->IsCommandEnabledForTab(
+ static_cast<TabStripModel::ContextMenuCommand>(command_id),
+ tab_index_);
+ }
+ virtual bool GetAcceleratorForCommandId(
+ int command_id,
+ menus::Accelerator* accelerator) {
+ return controller_->tabstrip_->GetWidget()->GetAccelerator(command_id,
+ accelerator);
+ }
+ virtual void ExecuteCommand(int command_id) {
+ controller_->ExecuteCommandForTab(
+ static_cast<TabStripModel::ContextMenuCommand>(command_id),
+ tab_index_);
+ }
+
+ private:
+ void Build() {
+ menu_.reset(new views::Menu2(&model_));
+ }
+
+ TabMenuModel model_;
+ scoped_ptr<views::Menu2> menu_;
+
+ // The index of the tab we are showing the context menu for.
+ int tab_index_;
+
+ // A pointer back to our hosting controller, for command state information.
+ BrowserTabStripController* controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(TabContextMenuContents);
+};
+
////////////////////////////////////////////////////////////////////////////////
// BrowserTabStripController, public:
@@ -18,6 +80,45 @@ BrowserTabStripController::BrowserTabStripController(TabStripModel* model,
}
BrowserTabStripController::~BrowserTabStripController() {
+ model_->RemoveObserver(this);
+}
+
+void BrowserTabStripController::InitFromModel() {
+ // Walk the model, calling our insertion observer method for each item within
+ // it.
+ for (int i = 0; i < model_->count(); ++i) {
+ TabInsertedAt(model_->GetTabContentsAt(i), i,
+ i == model_->selected_index());
+ }
+}
+
+bool BrowserTabStripController::IsCommandEnabledForTab(
+ TabStripModel::ContextMenuCommand command_id, int tab_index) const {
+ if (model_->ContainsIndex(tab_index))
+ return model_->IsContextMenuCommandEnabled(tab_index, command_id);
+ return false;
+}
+
+bool BrowserTabStripController::IsCommandCheckedForTab(
+ TabStripModel::ContextMenuCommand command_id, int tab_index) const {
+ // TODO(beng): move to TabStripModel, see note in IsTabPinned.
+ if (command_id == TabStripModel::CommandTogglePinned)
+ return false;
+
+ if (model_->ContainsIndex(tab_index))
+ return model_->IsContextMenuCommandChecked(tab_index, command_id);
+ return false;
+}
+
+void BrowserTabStripController::ExecuteCommandForTab(
+ TabStripModel::ContextMenuCommand command_id, int tab_index) {
+ if (model_->ContainsIndex(tab_index))
+ model_->ExecuteContextMenuCommand(tab_index, command_id);
+}
+
+bool BrowserTabStripController::IsTabPinned(int tab_index) {
+ return model_->ContainsIndex(tab_index) ?
+ model_->IsTabPinned(tab_index) : false;
}
////////////////////////////////////////////////////////////////////////////////
@@ -53,6 +154,12 @@ void BrowserTabStripController::CloseTab(int index) {
model_->CloseTabContentsAt(index);
}
+void BrowserTabStripController::ShowContextMenu(int index,
+ const gfx::Point& p) {
+ context_menu_contents_.reset(new TabContextMenuContents(index, this));
+ context_menu_contents_->RunMenuAt(p);
+}
+
////////////////////////////////////////////////////////////////////////////////
// BrowserTabStripController, TabStripModelObserver implementation:
diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.h b/chrome/browser/views/tabs/browser_tab_strip_controller.h
index e127659..f4a0295 100644
--- a/chrome/browser/views/tabs/browser_tab_strip_controller.h
+++ b/chrome/browser/views/tabs/browser_tab_strip_controller.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_VIEWS_TABS_BROWSER_TAB_STRIP_CONTROLLER_H_
#define CHROME_BROWSER_VIEWS_TABS_BROWSER_TAB_STRIP_CONTROLLER_H_
+#include "base/scoped_ptr.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/views/tabs/side_tab_strip_model.h"
@@ -18,6 +19,16 @@ class BrowserTabStripController : public SideTabStripModel,
BrowserTabStripController(TabStripModel* model, SideTabStrip* tabstrip);
virtual ~BrowserTabStripController();
+ void InitFromModel();
+
+ bool IsCommandEnabledForTab(TabStripModel::ContextMenuCommand command_id,
+ int tab_index) const;
+ bool IsCommandCheckedForTab(TabStripModel::ContextMenuCommand command_id,
+ int tab_index) const;
+ void ExecuteCommandForTab(TabStripModel::ContextMenuCommand command_id,
+ int tab_index);
+ bool IsTabPinned(int tab_index);
+
// SideTabStripModel implementation:
virtual SkBitmap GetIcon(int index) const;
virtual string16 GetTitle(int index) const;
@@ -25,6 +36,7 @@ class BrowserTabStripController : public SideTabStripModel,
virtual NetworkState GetNetworkState(int index) const;
virtual void SelectTab(int index);
virtual void CloseTab(int index);
+ virtual void ShowContextMenu(int index, const gfx::Point& p);
// TabStripModelObserver implementation:
virtual void TabInsertedAt(TabContents* contents, int index,
@@ -43,9 +55,14 @@ class BrowserTabStripController : public SideTabStripModel,
virtual void TabBlockedStateChanged(TabContents* contents, int index);
private:
+ class TabContextMenuContents;
+
TabStripModel* model_;
SideTabStrip* tabstrip_;
+ // If non-NULL it means we're showing a menu for the tab.
+ scoped_ptr<TabContextMenuContents> context_menu_contents_;
+
DISALLOW_COPY_AND_ASSIGN(BrowserTabStripController);
};
diff --git a/chrome/browser/views/tabs/side_tab.cc b/chrome/browser/views/tabs/side_tab.cc
index 9c45dd2..dfa18e1 100644
--- a/chrome/browser/views/tabs/side_tab.cc
+++ b/chrome/browser/views/tabs/side_tab.cc
@@ -57,6 +57,8 @@ SideTab::SideTab(SideTabModel* model)
hover_animation_.reset(new SlideAnimation(this));
hover_animation_->SetSlideDuration(kHoverDurationMs);
+
+ SetContextMenuController(this);
}
SideTab::~SideTab() {
@@ -111,6 +113,15 @@ void SideTab::ButtonPressed(views::Button* sender, const views::Event& event) {
}
////////////////////////////////////////////////////////////////////////////////
+// SideTab, views::ContextMenuController implementation:
+
+void SideTab::ShowContextMenu(views::View* source,
+ const gfx::Point& p,
+ bool is_mouse_gesture) {
+ model_->ShowContextMenu(this, p);
+}
+
+////////////////////////////////////////////////////////////////////////////////
// SideTab, views::View overrides:
void SideTab::Layout() {
@@ -120,14 +131,19 @@ void SideTab::Layout() {
gfx::Size ps = close_button_->GetPreferredSize();
int close_y = (height() - ps.height()) / 2;
- close_button_->SetBounds(width() - ps.width() - close_y, close_y, ps.width(),
- ps.height());
+ close_button_->SetBounds(
+ std::max(0, width() - ps.width() - close_y),
+ close_y,
+ ps.width(),
+ ps.height());
int title_y = (height() - font_->height()) / 2;
int title_x = icon_bounds_.right() + kIconTitleSpacing;
- title_bounds_.SetRect(title_x, title_y,
- close_button_->x() - kTitleCloseSpacing - title_x,
- font_->height());
+ title_bounds_.SetRect(
+ title_x,
+ title_y,
+ std::max(0, close_button_->x() - kTitleCloseSpacing - title_x),
+ font_->height());
}
void SideTab::Paint(gfx::Canvas* canvas) {
diff --git a/chrome/browser/views/tabs/side_tab.h b/chrome/browser/views/tabs/side_tab.h
index b267d5a..7c0e9d6 100644
--- a/chrome/browser/views/tabs/side_tab.h
+++ b/chrome/browser/views/tabs/side_tab.h
@@ -26,9 +26,13 @@ class SideTabModel {
// Closes the tab.
virtual void CloseTab(SideTab* tab) = 0;
+
+ // Shows a context menu for the tab at the specified point in screen coords.
+ virtual void ShowContextMenu(SideTab* tab, const gfx::Point& p) = 0;
};
class SideTab : public views::View,
+ public views::ContextMenuController,
public views::ButtonListener,
public AnimationDelegate {
public:
@@ -48,6 +52,11 @@ class SideTab : public views::View,
// views::ButtonListener implementation:
virtual void ButtonPressed(views::Button* sender, const views::Event& event);
+ // views::ContextMenuController implementation:
+ virtual void ShowContextMenu(views::View* source,
+ const gfx::Point& p,
+ bool is_mouse_gesture);
+
// views::View Overrides:
virtual void Layout();
virtual void Paint(gfx::Canvas* canvas);
diff --git a/chrome/browser/views/tabs/side_tab_strip.cc b/chrome/browser/views/tabs/side_tab_strip.cc
index 7ef38d6..c7a343c 100644
--- a/chrome/browser/views/tabs/side_tab_strip.cc
+++ b/chrome/browser/views/tabs/side_tab_strip.cc
@@ -4,13 +4,7 @@
#include "chrome/browser/views/tabs/side_tab_strip.h"
-#include "base/command_line.h"
-#include "chrome/browser/pref_service.h"
-#include "chrome/browser/profile.h"
#include "chrome/browser/view_ids.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/common/pref_names.h"
-#include "gfx/canvas.h"
namespace {
const int kVerticalTabSpacing = 2;
@@ -32,18 +26,6 @@ void SideTabStrip::SetModel(SideTabStripModel* model) {
model_.reset(model);
}
-// static
-bool SideTabStrip::Available() {
- return CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableVerticalTabs);
-}
-
-// static
-bool SideTabStrip::Visible(Profile* profile) {
- return Available() &&
- profile->GetPrefs()->GetBoolean(prefs::kUseVerticalTabs);
-}
-
void SideTabStrip::AddTabAt(int index) {
SideTab* tab = new SideTab(this);
AddChildView(tab);
@@ -88,6 +70,10 @@ void SideTabStrip::CloseTab(SideTab* tab) {
model_->CloseTab(GetIndexOfSideTab(tab));
}
+void SideTabStrip::ShowContextMenu(SideTab* tab, const gfx::Point& p) {
+ model_->ShowContextMenu(GetIndexOfSideTab(tab), p);
+}
+
////////////////////////////////////////////////////////////////////////////////
// SideTabStrip, BaseTabStrip implementation:
diff --git a/chrome/browser/views/tabs/side_tab_strip.h b/chrome/browser/views/tabs/side_tab_strip.h
index 71b704a..558d1a1 100644
--- a/chrome/browser/views/tabs/side_tab_strip.h
+++ b/chrome/browser/views/tabs/side_tab_strip.h
@@ -21,14 +21,6 @@ class SideTabStrip : public BaseTabStrip,
// Associate a model with this SideTabStrip. The SideTabStrip owns its model.
void SetModel(SideTabStripModel* model);
- // Whether or not the browser has been run with the "enable-vertical-tabs"
- // command line flag that allows the SideTabStrip to be optionally shown.
- static bool Available();
-
- // Whether or not the vertical tabstrip is shown. Only valid if Available()
- // returns true.
- static bool Visible(Profile* profile);
-
// Notifies the SideTabStrip that a tab was added in the model at |index|.
void AddTabAt(int index);
@@ -48,6 +40,7 @@ class SideTabStrip : public BaseTabStrip,
virtual bool IsSelected(SideTab* tab) const;
virtual void SelectTab(SideTab* tab);
virtual void CloseTab(SideTab* tab);
+ virtual void ShowContextMenu(SideTab* tab, const gfx::Point& p);
// BaseTabStrip implementation:
virtual int GetPreferredHeight();
diff --git a/chrome/browser/views/tabs/side_tab_strip_model.h b/chrome/browser/views/tabs/side_tab_strip_model.h
index a456c36..835e5ba 100644
--- a/chrome/browser/views/tabs/side_tab_strip_model.h
+++ b/chrome/browser/views/tabs/side_tab_strip_model.h
@@ -7,12 +7,17 @@
#include "base/string16.h"
+namespace gfx {
+class Point;
+}
class SkBitmap;
// A model interface implemented by an object that can provide information
// about SideTabs in a SideTabStrip.
class SideTabStripModel {
public:
+ virtual ~SideTabStripModel() {}
+
// Returns metadata about the tab at the specified index.
virtual SkBitmap GetIcon(int index) const = 0;
virtual string16 GetTitle(int index) const = 0;
@@ -35,6 +40,10 @@ class SideTabStripModel {
// Closes the tab at the specified index in the model.
virtual void CloseTab(int index) = 0;
+
+ // Shows a context menu for the tab at the specified index at the specified
+ // point in screen coords.
+ virtual void ShowContextMenu(int index, const gfx::Point& p) = 0;
};
#endif // CHROME_BROWSER_VIEWS_TABS_SIDE_TAB_STRIP_MODEL_H_
diff --git a/chrome/browser/views/tabs/tab.cc b/chrome/browser/views/tabs/tab.cc
index eb80e89..4f3989c 100644
--- a/chrome/browser/views/tabs/tab.cc
+++ b/chrome/browser/views/tabs/tab.cc
@@ -52,7 +52,9 @@ class Tab::TabContextMenuContents : public menus::SimpleMenuModel::Delegate {
// Overridden from menus::SimpleMenuModel::Delegate:
virtual bool IsCommandIdChecked(int command_id) const {
- return false;
+ return tab_ && tab_->delegate()->IsCommandCheckedForTab(
+ static_cast<TabStripModel::ContextMenuCommand>(command_id),
+ tab_);
}
virtual bool IsCommandIdEnabled(int command_id) const {
return tab_ && tab_->delegate()->IsCommandEnabledForTab(
diff --git a/chrome/browser/views/tabs/tab.h b/chrome/browser/views/tabs/tab.h
index 79b08f2..2276239 100644
--- a/chrome/browser/views/tabs/tab.h
+++ b/chrome/browser/views/tabs/tab.h
@@ -46,6 +46,10 @@ class Tab : public TabRenderer,
virtual bool IsCommandEnabledForTab(
TabStripModel::ContextMenuCommand command_id, const Tab* tab) const = 0;
+ // Returns true if the specified command is checked for the specified Tab.
+ virtual bool IsCommandCheckedForTab(
+ TabStripModel::ContextMenuCommand command_id, const Tab* tab) const = 0;
+
// Executes the specified command for the specified Tab.
virtual void ExecuteCommandForTab(
TabStripModel::ContextMenuCommand command_id, Tab* tab) = 0;
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
index 7f31722..a6e11d3 100644
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ b/chrome/browser/views/tabs/tab_strip.cc
@@ -265,8 +265,7 @@ TabStrip::~TabStrip() {
// delete the tabs.
StopAnimating(false);
- // TODO(beng): (1031854) Restore this line once XPFrame/VistaFrame are dead.
- // model_->RemoveObserver(this);
+ model_->RemoveObserver(this);
// TODO(beng): remove this if it doesn't work to fix the TabSelectedAt bug.
drag_controller_.reset(NULL);
@@ -341,6 +340,15 @@ gfx::Rect TabStrip::GetNewTabButtonBounds() {
return newtab_button_->bounds();
}
+void TabStrip::InitFromModel() {
+ // Walk the model, calling our insertion observer method for each item within
+ // it.
+ for (int i = 0; i < model_->count(); ++i) {
+ TabInsertedAt(model_->GetTabContentsAt(i), i,
+ i == model_->selected_index());
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
// TabStrip, BaseTabStrip implementation:
@@ -866,6 +874,14 @@ bool TabStrip::IsCommandEnabledForTab(
return false;
}
+bool TabStrip::IsCommandCheckedForTab(
+ TabStripModel::ContextMenuCommand command_id, const Tab* tab) const {
+ int model_index = GetModelIndexOfTab(tab);
+ if (model_->ContainsIndex(model_index))
+ return model_->IsContextMenuCommandChecked(model_index, command_id);
+ return false;
+}
+
void TabStrip::ExecuteCommandForTab(
TabStripModel::ContextMenuCommand command_id, Tab* tab) {
int model_index = GetModelIndexOfTab(tab);
diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h
index 95ccfdb..8752bf1 100644
--- a/chrome/browser/views/tabs/tab_strip.h
+++ b/chrome/browser/views/tabs/tab_strip.h
@@ -95,6 +95,11 @@ class TabStrip : public BaseTabStrip,
// Returns the bounds of the new tab button.
gfx::Rect GetNewTabButtonBounds();
+ // Populates the BaseTabStrip implementation from its model. This is primarily
+ // useful when switching between display types and there are existing tabs.
+ // Upon initial creation the TabStrip is empty.
+ void InitFromModel();
+
// BaseTabStrip implementation:
virtual int GetPreferredHeight();
virtual void SetBackgroundOffset(const gfx::Point& offset);
@@ -161,6 +166,8 @@ class TabStrip : public BaseTabStrip,
virtual void CloseTab(Tab* tab);
virtual bool IsCommandEnabledForTab(
TabStripModel::ContextMenuCommand command_id, const Tab* tab) const;
+ virtual bool IsCommandCheckedForTab(
+ TabStripModel::ContextMenuCommand command_id, const Tab* tab) const;
virtual void ExecuteCommandForTab(
TabStripModel::ContextMenuCommand command_id, Tab* tab);
virtual void StartHighlightTabsForCommand(
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index eb9c51aa..d2463a5 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -629,7 +629,8 @@ class NotificationType {
// the profile. No details are provided.
WEB_APP_INSTALL_CHANGED,
- // This is sent to a pref observer when a pref is changed.
+ // This is sent to a pref observer when a pref is changed. The source is the
+ // PrefService and the details a std::wstring of the changed path.
PREF_CHANGED,
// Sent when a default request context has been created, so calling
diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h
index 9f384f6..701ccf0 100644
--- a/chrome/test/test_browser_window.h
+++ b/chrome/test/test_browser_window.h
@@ -100,6 +100,7 @@ class TestBrowserWindow : public BrowserWindow {
virtual void Cut() { }
virtual void Copy() { }
virtual void Paste() { }
+ virtual void ToggleTabStripMode() {}
protected:
virtual void DestroyBrowser() {}