summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/nibs/BrowserWindow.xib108
-rw-r--r--chrome/app/nibs/TabContents.xib102
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h13
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm123
-rw-r--r--chrome/browser/cocoa/browser_window_controller_private.mm8
-rw-r--r--chrome/browser/cocoa/dev_tools_controller.h48
-rw-r--r--chrome/browser/cocoa/dev_tools_controller.mm105
-rw-r--r--chrome/browser/cocoa/infobar_container_controller.h26
-rw-r--r--chrome/browser/cocoa/infobar_container_controller.mm66
-rw-r--r--chrome/browser/cocoa/infobar_container_controller_unittest.mm6
-rw-r--r--chrome/browser/cocoa/side_tab_strip_controller.mm8
-rw-r--r--chrome/browser/cocoa/sidebar_controller.h50
-rw-r--r--chrome/browser/cocoa/sidebar_controller.mm124
-rw-r--r--chrome/browser/cocoa/tab_contents_controller.h43
-rw-r--r--chrome/browser/cocoa/tab_contents_controller.mm175
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.h29
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm102
-rw-r--r--chrome/browser/cocoa/tab_strip_controller_unittest.mm19
-rw-r--r--chrome/browser/cocoa/tab_window_controller.h10
-rw-r--r--chrome/browser/cocoa/tab_window_controller.mm2
-rw-r--r--chrome/chrome_browser.gypi4
21 files changed, 704 insertions, 467 deletions
diff --git a/chrome/app/nibs/BrowserWindow.xib b/chrome/app/nibs/BrowserWindow.xib
index 30b1c8f..022c2b2 100644
--- a/chrome/app/nibs/BrowserWindow.xib
+++ b/chrome/app/nibs/BrowserWindow.xib
@@ -12,6 +12,7 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <integer value="1"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -48,19 +49,41 @@
<string key="NSWindowContentMaxSize">{1.79769e+308, 1.79769e+308}</string>
<string key="NSWindowContentMinSize">{400, 250}</string>
<object class="NSView" key="NSWindowView" id="1006">
- <nil key="NSNextResponder"/>
+ <reference key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSCustomView" id="1858870">
<reference key="NSNextResponder" ref="1006"/>
<int key="NSvFlags">274</int>
- <string key="NSFrameSize">{750, 586}</string>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSSplitView" id="321204824">
+ <reference key="NSNextResponder" ref="1858870"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSSplitView" id="267972061">
+ <reference key="NSNextResponder" ref="321204824"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrameSize">{750, 600}</string>
+ <reference key="NSSuperview" ref="321204824"/>
+ <bool key="NSIsVertical">YES</bool>
+ <int key="NSDividerStyle">2</int>
+ </object>
+ </object>
+ <string key="NSFrameSize">{750, 600}</string>
+ <reference key="NSSuperview" ref="1858870"/>
+ <int key="NSDividerStyle">2</int>
+ </object>
+ </object>
+ <string key="NSFrameSize">{750, 600}</string>
<reference key="NSSuperview" ref="1006"/>
<string key="NSClassName">FastResizeView</string>
</object>
</object>
<string key="NSFrameSize">{750, 600}</string>
+ <reference key="NSSuperview"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMinSize">{400, 272}</string>
@@ -157,6 +180,22 @@
</object>
<int key="connectionID">90</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">devToolsContainer_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="321204824"/>
+ </object>
+ <int key="connectionID">94</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">contentsContainer_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="267972061"/>
+ </object>
+ <int key="connectionID">98</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -229,14 +268,32 @@
<reference key="parent" ref="131944810"/>
</object>
<object class="IBObjectRecord">
+ <int key="objectID">89</int>
+ <reference key="object" ref="529166964"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
<int key="objectID">84</int>
<reference key="object" ref="1858870"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="321204824"/>
+ </object>
<reference key="parent" ref="1006"/>
</object>
<object class="IBObjectRecord">
- <int key="objectID">89</int>
- <reference key="object" ref="529166964"/>
- <reference key="parent" ref="0"/>
+ <int key="objectID">91</int>
+ <reference key="object" ref="321204824"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="267972061"/>
+ </object>
+ <reference key="parent" ref="1858870"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">95</int>
+ <reference key="object" ref="267972061"/>
+ <reference key="parent" ref="321204824"/>
</object>
</object>
</object>
@@ -268,15 +325,17 @@
<string>84.IBPluginDependency</string>
<string>89.IBEditorWindowLastContentRect</string>
<string>89.IBPluginDependency</string>
+ <string>91.IBPluginDependency</string>
+ <string>95.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{267, 167}, {750, 600}}</string>
+ <string>{{319, 325}, {750, 600}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{267, 167}, {750, 600}}</string>
+ <string>{{319, 325}, {750, 600}}</string>
<boolean value="NO"/>
<string>{196, 240}</string>
<string>{{357, 418}, {480, 270}}</string>
@@ -298,6 +357,8 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{89, 611}, {236, 393}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -316,7 +377,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">90</int>
+ <int key="maxID">98</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -337,6 +398,14 @@
</object>
</object>
<object class="IBPartialClassDescription">
+ <string key="className">ChromeBrowserWindow</string>
+ <string key="superclassName">ChromeEventProcessingWindow</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">browser/cocoa/chrome_browser_window.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
<string key="className">ChromeEventProcessingWindow</string>
<string key="superclassName">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -373,7 +442,7 @@
</object>
<object class="IBPartialClassDescription">
<string key="className">FramedBrowserWindow</string>
- <string key="superclassName">ChromeEventProcessingWindow</string>
+ <string key="superclassName">ChromeBrowserWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier" id="623970533">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">browser/cocoa/framed_browser_window.h</string>
@@ -467,12 +536,16 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>contentsContainer_</string>
+ <string>devToolsContainer_</string>
<string>sideTabStripView_</string>
<string>tabContentArea_</string>
<string>topTabStripView_</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSSplitView</string>
+ <string>NSSplitView</string>
<string>TabStripView</string>
<string>FastResizeView</string>
<string>TabStripView</string>
@@ -482,6 +555,8 @@
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
+ <string>contentsContainer_</string>
+ <string>devToolsContainer_</string>
<string>sideTabStripView_</string>
<string>tabContentArea_</string>
<string>topTabStripView_</string>
@@ -489,6 +564,14 @@
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
+ <string key="name">contentsContainer_</string>
+ <string key="candidateClassName">NSSplitView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
+ <string key="name">devToolsContainer_</string>
+ <string key="candidateClassName">NSSplitView</string>
+ </object>
+ <object class="IBToOneOutletInfo">
<string key="name">sideTabStripView_</string>
<string key="candidateClassName">TabStripView</string>
</object>
@@ -785,7 +868,7 @@
</object>
<object class="IBPartialClassDescription">
<string key="className">NSObject</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <object class="IBClassDescriptionSource" key="sourceIdentifier" id="996113394">
<string key="majorKey">IBFrameworkSource</string>
<string key="minorKey">AppKit.framework/Headers/NSSplitView.h</string>
</object>
@@ -1114,6 +1197,11 @@
</object>
</object>
<object class="IBPartialClassDescription">
+ <string key="className">NSSplitView</string>
+ <string key="superclassName">NSView</string>
+ <reference key="sourceIdentifier" ref="996113394"/>
+ </object>
+ <object class="IBPartialClassDescription">
<string key="className">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBFrameworkSource</string>
diff --git a/chrome/app/nibs/TabContents.xib b/chrome/app/nibs/TabContents.xib
index d93dcbb..2419109 100644
--- a/chrome/app/nibs/TabContents.xib
+++ b/chrome/app/nibs/TabContents.xib
@@ -12,7 +12,7 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="213"/>
+ <integer value="94"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -57,27 +57,6 @@
<object class="NSView" key="NSWindowView" id="675542922">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
- <object class="NSMutableArray" key="NSSubviews">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSSplitView" id="89435107">
- <reference key="NSNextResponder" ref="675542922"/>
- <int key="NSvFlags">274</int>
- <object class="NSMutableArray" key="NSSubviews">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSSplitView" id="901624045">
- <reference key="NSNextResponder" ref="89435107"/>
- <int key="NSvFlags">268</int>
- <string key="NSFrameSize">{480, 360}</string>
- <reference key="NSSuperview" ref="89435107"/>
- <bool key="NSIsVertical">YES</bool>
- <int key="NSDividerStyle">2</int>
- </object>
- </object>
- <string key="NSFrameSize">{480, 360}</string>
- <reference key="NSSuperview" ref="675542922"/>
- <int key="NSDividerStyle">2</int>
- </object>
- </object>
<string key="NSFrameSize">{480, 360}</string>
<reference key="NSSuperview"/>
</object>
@@ -97,22 +76,6 @@
</object>
<int key="connectionID">156</int>
</object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
- <string key="label">devToolsContainer_</string>
- <reference key="source" ref="326691890"/>
- <reference key="destination" ref="89435107"/>
- </object>
- <int key="connectionID">212</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
- <string key="label">contentsContainer_</string>
- <reference key="source" ref="326691890"/>
- <reference key="destination" ref="901624045"/>
- </object>
- <int key="connectionID">216</int>
- </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -150,7 +113,6 @@
<reference key="object" ref="675542922"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="89435107"/>
</object>
<reference key="parent" ref="886393115"/>
</object>
@@ -160,23 +122,6 @@
<reference key="parent" ref="0"/>
<string key="objectName">Application</string>
</object>
- <object class="IBObjectRecord">
- <int key="objectID">195</int>
- <reference key="object" ref="89435107"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="901624045"/>
- </object>
- <reference key="parent" ref="675542922"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">213</int>
- <reference key="object" ref="901624045"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- </object>
- <reference key="parent" ref="89435107"/>
- </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -184,8 +129,6 @@
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-3.IBPluginDependency</string>
- <string>195.IBPluginDependency</string>
- <string>213.IBPluginDependency</string>
<string>93.IBEditorWindowLastContentRect</string>
<string>93.IBPluginDependency</string>
<string>93.IBViewEditorWindowController.showingLayoutRectangles</string>
@@ -199,12 +142,10 @@
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{529, 843}, {480, 360}}</string>
+ <string>{{1428, 763}, {480, 360}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="YES"/>
- <string>{{529, 843}, {480, 360}}</string>
+ <string>{{1428, 763}, {480, 360}}</string>
<boolean value="YES"/>
<boolean value="YES"/>
<string>{480, 360}</string>
@@ -228,7 +169,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">216</int>
+ <int key="maxID">221</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -291,7 +232,7 @@
<string key="className">NSWindow</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
- <string key="minorKey">browser/cocoa/chrome_browser_window.h</string>
+ <string key="minorKey">browser/cocoa/framed_browser_window.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
@@ -305,35 +246,14 @@
<string key="className">TabContentsController</string>
<string key="superclassName">NSViewController</string>
<object class="NSMutableDictionary" key="outlets">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>contentsContainer_</string>
- <string>devToolsContainer_</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>NSSplitView</string>
- <string>NSSplitView</string>
- </object>
+ <string key="NS.key.0">contentsContainer_</string>
+ <string key="NS.object.0">NSSplitView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>contentsContainer_</string>
- <string>devToolsContainer_</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBToOneOutletInfo">
- <string key="name">contentsContainer_</string>
- <string key="candidateClassName">NSSplitView</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">devToolsContainer_</string>
- <string key="candidateClassName">NSSplitView</string>
- </object>
+ <string key="NS.key.0">contentsContainer_</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">contentsContainer_</string>
+ <string key="candidateClassName">NSSplitView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h
index c971777..7bbbe96 100644
--- a/chrome/browser/cocoa/browser_window_controller.h
+++ b/chrome/browser/cocoa/browser_window_controller.h
@@ -17,7 +17,10 @@
#include "base/scoped_ptr.h"
#import "chrome/browser/cocoa/bookmark_bar_controller.h"
#import "chrome/browser/cocoa/bookmark_bubble_controller.h"
+#import "chrome/browser/cocoa/dev_tools_controller.h"
#import "chrome/browser/cocoa/browser_command_executor.h"
+#import "chrome/browser/cocoa/sidebar_controller.h"
+#import "chrome/browser/cocoa/tab_strip_controller.h"
#import "chrome/browser/cocoa/tab_window_controller.h"
#import "chrome/browser/cocoa/themed_window.h"
#import "chrome/browser/cocoa/url_drop_target.h"
@@ -39,7 +42,6 @@ class LocationBarViewMac;
class StatusBubbleMac;
class TabContents;
@class TabStripController;
-class TabStripModelObserverBridge;
@class TabStripView;
@class ToolbarController;
@@ -48,7 +50,10 @@ class TabStripModelObserverBridge;
TabWindowController<NSUserInterfaceValidations,
BookmarkBarControllerDelegate,
BrowserCommandExecutor,
- ViewResizer> {
+ ViewResizer,
+ DevToolsControllerDelegate,
+ SidebarControllerDelegate,
+ TabStripControllerDelegate> {
@private
// The ordering of these members is important as it determines the order in
// which they are destroyed. |browser_| needs to be destroyed last as most of
@@ -56,7 +61,6 @@ class TabStripModelObserverBridge;
// (tab/toolbar/bookmark models, profiles, etc).
scoped_ptr<Browser> browser_;
NSWindow* savedRegularWindow_;
- scoped_ptr<TabStripModelObserverBridge> tabObserver_;
scoped_ptr<BrowserWindowCocoa> windowShim_;
scoped_nsobject<ToolbarController> toolbarController_;
scoped_nsobject<TabStripController> tabStripController_;
@@ -64,6 +68,8 @@ class TabStripModelObserverBridge;
scoped_nsobject<InfoBarContainerController> infoBarContainerController_;
scoped_nsobject<DownloadShelfController> downloadShelfController_;
scoped_nsobject<BookmarkBarController> bookmarkBarController_;
+ scoped_nsobject<DevToolsController> devToolsController_;
+ scoped_nsobject<SidebarController> sidebarController_;
scoped_nsobject<FullscreenController> fullscreenController_;
// Strong. StatusBubble is a special case of a strong reference that
@@ -75,7 +81,6 @@ class TabStripModelObserverBridge;
BookmarkBubbleController* bookmarkBubbleController_; // Weak.
BOOL initializing_; // YES while we are currently in initWithBrowser:
BOOL ownsBrowser_; // Only ever NO when testing
- CGFloat verticalOffsetForStatusBubble_;
// The total amount by which we've grown the window up or down (to display a
// bookmark bar and/or download shelf), respectively; reset to 0 when moved
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index e4fc9ce..b2ec489 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -36,7 +36,6 @@
#import "chrome/browser/cocoa/status_bubble_mac.h"
#import "chrome/browser/cocoa/tab_contents_controller.h"
#import "chrome/browser/cocoa/tab_strip_controller.h"
-#import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
#import "chrome/browser/cocoa/tab_strip_view.h"
#import "chrome/browser/cocoa/tab_view.h"
#import "chrome/browser/cocoa/tabpose_window.h"
@@ -56,7 +55,6 @@
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
-
// ORGANIZATION: This is a big file. It is (in principle) organized as follows
// (in order):
// 1. Interfaces. Very short, one-time-use classes may include an implementation
@@ -191,8 +189,6 @@
initializing_ = YES;
browser_.reset(browser);
ownsBrowser_ = ownIt;
- tabObserver_.reset(
- new TabStripModelObserverBridge(browser->tabstrip_model(), self));
NSWindow* window = [self window];
windowShim_.reset(new BrowserWindowCocoa(browser, self, window));
@@ -240,9 +236,7 @@
// Create the infobar container view, so we can pass it to the
// ToolbarController.
infoBarContainerController_.reset(
- [[InfoBarContainerController alloc]
- initWithTabStripModel:(browser_->tabstrip_model())
- resizeDelegate:self]);
+ [[InfoBarContainerController alloc] initWithResizeDelegate:self]);
[[[self window] contentView] addSubview:[infoBarContainerController_ view]];
// Create a controller for the toolbar, giving it the toolbar model object
@@ -276,6 +270,16 @@
relativeTo:[toolbarController_ view]];
[bookmarkBarController_ setBookmarkBarEnabled:[self supportsBookmarkBar]];
+ // Create a sub-controller for the docked devTools.
+ devToolsController_.reset(
+ [[DevToolsController alloc] initWithView:[self devToolsContainer]
+ delegate:self]);
+
+ // Create a sub-controller for the docked devTools.
+ sidebarController_.reset(
+ [[SidebarController alloc] initWithView:[self contentsContainer]
+ delegate:self]);
+
// We don't want to try and show the bar before it gets placed in its parent
// view, so this step shoudn't be inside the bookmark bar controller's
// |-awakeFromNib|.
@@ -396,11 +400,11 @@
}
- (void)updateDevToolsForContents:(TabContents*)contents {
- [tabStripController_ updateDevToolsForContents:contents];
+ [devToolsController_ updateDevToolsForTabContents:contents];
}
- (void)updateSidebarForContents:(TabContents*)contents {
- [tabStripController_ updateSidebarForContents:contents];
+ [sidebarController_ updateSidebarForTabContents:contents];
}
// Called when the user wants to close a window or from the shutdown process.
@@ -979,9 +983,13 @@
// StatusBubble delegate method: tell the status bubble how far above the bottom
// of the window it should position itself.
+// TODO(alekseys): status bubble should respect web view bounds, not just its
+// vertical size. Now it can overlap sidebar contents. http://crbug.com/54882
- (CGFloat)verticalOffsetForStatusBubble {
- return verticalOffsetForStatusBubble_ +
- [[tabStripController_ activeTabContentsController] devToolsHeight];
+ NSRect contents_bounds = [[self contentsContainer] bounds];
+ NSView* baseView = [[self window] contentView];
+ return NSMinY([baseView convertRect:contents_bounds
+ fromView:[self contentsContainer]]);
}
- (GTMWindowSheetController*)sheetController {
@@ -1297,41 +1305,90 @@
return [self supportsWindowFeature:Browser::FEATURE_TABSTRIP];
}
-- (void)selectTabWithContents:(TabContents*)newContents
- previousContents:(TabContents*)oldContents
- atIndex:(NSInteger)index
- userGesture:(bool)wasUserGesture {
- DCHECK(oldContents != newContents);
+// DevToolsController protocol.
+- (void)resizeDevToolsToNewHeight:(CGFloat)height {
+ NSSplitView* container = [self devToolsContainer];
+ NSArray* subviews = [container subviews];
+
+ // It seems as if |-setPosition:ofDividerAtIndex:| should do what's needed,
+ // but I can't figure out how to use it. Manually resize web and devtools.
+ // TODO(alekseys): either make setPosition:ofDividerAtIndex: work or to add a
+ // category on NSSplitView to handle manual resizing.
+ NSView* devToolsView = [subviews objectAtIndex:1];
+ NSRect devToolsFrame = [devToolsView frame];
+ devToolsFrame.size.height = height;
+ [devToolsView setFrame:devToolsFrame];
+
+ NSView* webView = [subviews objectAtIndex:0];
+ NSRect webFrame = [webView frame];
+ webFrame.size.height =
+ NSHeight([container frame]) - ([container dividerThickness] + height);
+ [webView setFrame:webFrame];
+
+ [container adjustSubviews];
+}
+
+// SidebarController protocol.
+- (void)resizeSidebarToNewWidth:(CGFloat)width {
+ NSSplitView* container = [self contentsContainer];
+ NSArray* subviews = [container subviews];
+
+ // It seems as if |-setPosition:ofDividerAtIndex:| should do what's needed,
+ // but I can't figure out how to use it. Manually resize web and sidebar.
+ // TODO(alekseys): either make setPosition:ofDividerAtIndex: work or to add a
+ // category on NSSplitView to handle manual resizing.
+ NSView* sidebarView = [subviews objectAtIndex:1];
+ NSRect sidebarFrame = [sidebarView frame];
+ sidebarFrame.size.width = width;
+ [sidebarView setFrame:sidebarFrame];
+
+ NSView* webView = [subviews objectAtIndex:0];
+ NSRect webFrame = [webView frame];
+ webFrame.size.width =
+ NSWidth([container frame]) - ([container dividerThickness] + width);
+ [webView setFrame:webFrame];
+ [container adjustSubviews];
+}
+
+// TabStripControllerDelegate protocol.
+- (void)onSelectTabWithContents:(TabContents*)contents {
// Update various elements that are interested in knowing the current
// TabContents.
// Update all the UI bits.
windowShim_->UpdateTitleBar();
+ [self updateSidebarForContents:contents];
+ [self updateDevToolsForContents:contents];
+
// Update the bookmark bar.
+ // Must do it after sidebar and devtools update, otherwise bookmark bar might
+ // call resizeView -> layoutSubviews and cause unnecessary relayout.
// TODO(viettrungluu): perhaps update to not terminate running animations (if
// applicable)?
[self updateBookmarkBarVisibilityWithAnimation:NO];
+
+ [infoBarContainerController_ changeTabContents:contents];
}
-- (void)tabChangedWithContents:(TabContents*)contents
- atIndex:(NSInteger)index
- changeType:(TabStripModelObserver::TabChangeType)change {
- if (index == browser_->tabstrip_model()->selected_index()) {
- // Update titles if this is the currently selected tab and if it isn't just
- // the loading state which changed.
- if (change != TabStripModelObserver::LOADING_ONLY)
- windowShim_->UpdateTitleBar();
-
- // Update the bookmark bar if this is the currently selected tab and if it
- // isn't just the title which changed. This for transitions between the NTP
- // (showing its floating bookmark bar) and normal web pages (showing no
- // bookmark bar).
- // TODO(viettrungluu): perhaps update to not terminate running animations?
- if (change != TabStripModelObserver::TITLE_NOT_LOADING)
- [self updateBookmarkBarVisibilityWithAnimation:NO];
- }
+- (void)onSelectedTabChange:(TabStripModelObserver::TabChangeType)change {
+ // Update titles if this is the currently selected tab and if it isn't just
+ // the loading state which changed.
+ if (change != TabStripModelObserver::LOADING_ONLY)
+ windowShim_->UpdateTitleBar();
+
+ // Update the bookmark bar if this is the currently selected tab and if it
+ // isn't just the title which changed. This for transitions between the NTP
+ // (showing its floating bookmark bar) and normal web pages (showing no
+ // bookmark bar).
+ // TODO(viettrungluu): perhaps update to not terminate running animations?
+ if (change != TabStripModelObserver::TITLE_NOT_LOADING)
+ [self updateBookmarkBarVisibilityWithAnimation:NO];
+}
+
+- (void)onTabDetachedWithContents:(TabContents*)contents {
+ [infoBarContainerController_ tabDetachedWithContents:contents];
}
- (void)userChangedTheme {
diff --git a/chrome/browser/cocoa/browser_window_controller_private.mm b/chrome/browser/cocoa/browser_window_controller_private.mm
index 35ea1e0..1fbd31e 100644
--- a/chrome/browser/cocoa/browser_window_controller_private.mm
+++ b/chrome/browser/cocoa/browser_window_controller_private.mm
@@ -52,8 +52,9 @@ const CGFloat kLocBarBottomInset = 1;
tabStripController_.reset([[factory alloc]
initWithView:[self tabStripView]
- switchView:[self tabContentArea]
- browser:browser_.get()]);
+ switchView:[self contentsContainer]
+ browser:browser_.get()
+ delegate:self]);
}
- (void)saveWindowPositionIfNeeded {
@@ -229,9 +230,6 @@ willPositionSheet:(NSWindow*)sheet
NSRect contentAreaRect = NSMakeRect(minX, minY, width, maxY - minY);
[self layoutTabContentArea:contentAreaRect];
- // Place the status bubble at the bottom of the content area.
- verticalOffsetForStatusBubble_ = minY;
-
// Normally, we don't need to tell the toolbar whether or not to show the
// divider, but things break down during animation.
[toolbarController_
diff --git a/chrome/browser/cocoa/dev_tools_controller.h b/chrome/browser/cocoa/dev_tools_controller.h
new file mode 100644
index 0000000..1d6254e5
--- /dev/null
+++ b/chrome/browser/cocoa/dev_tools_controller.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 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_COCOA_DEV_TOOLS_CONTROLLER_H_
+#define CHROME_BROWSER_COCOA_DEV_TOOLS_CONTROLLER_H_
+#pragma once
+
+#import <Foundation/Foundation.h>
+
+#include "base/scoped_nsobject.h"
+
+@class NSSplitView;
+@class NSView;
+
+class TabContents;
+
+// DevTools controller's delegate interface. Delegate is responsible
+// for the actual subviews resize and layout.
+@protocol DevToolsControllerDelegate
+
+// Resizes the devTools view to the new |height| and adjusts window layout
+// accordingly.
+- (void)resizeDevToolsToNewHeight:(CGFloat)height;
+
+@end
+
+// A class that handles updates of the devTools view within a browser window.
+// It swaps in the relevant devTools contents for a given TabContents or removes
+// the vew, if there's no devTools contents to show.
+@interface DevToolsController : NSObject {
+ @private
+ // A view hosting docked devTools contents.
+ scoped_nsobject<NSSplitView> devToolsView_;
+ id<DevToolsControllerDelegate> delegate_; // weak
+}
+
+- (id)initWithView:(NSSplitView*)devToolsView
+ delegate:(id<DevToolsControllerDelegate>)delegate;
+
+// Depending on |contents|'s state, decides whether the docked web inspector
+// should be shown or hidden and adjusts its height (|delegate_| handles
+// the actual resize).
+- (void)updateDevToolsForTabContents:(TabContents*)contents;
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_DEV_TOOLS_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/dev_tools_controller.mm b/chrome/browser/cocoa/dev_tools_controller.mm
new file mode 100644
index 0000000..1a7e3b6
--- /dev/null
+++ b/chrome/browser/cocoa/dev_tools_controller.mm
@@ -0,0 +1,105 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/cocoa/dev_tools_controller.h"
+
+#include <algorithm>
+
+#include <Cocoa/Cocoa.h>
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_process.h"
+#import "chrome/browser/cocoa/view_id_util.h"
+#include "chrome/browser/debugger/devtools_window.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/pref_names.h"
+
+namespace {
+
+// Default offset of the contents splitter in pixels.
+const int kDefaultContentsSplitOffset = 400;
+
+// Never make the web part of the tab contents smaller than this (needed if the
+// window is only a few pixels high).
+const int kMinWebHeight = 50;
+
+} // end namespace
+
+
+@interface DevToolsController (Private)
+- (void)showDevToolsContents:(TabContents*)devToolsContents;
+@end
+
+
+@implementation DevToolsController
+
+- (id)initWithView:(NSSplitView*)devToolsView
+ delegate:(id<DevToolsControllerDelegate>)delegate {
+ DCHECK(delegate);
+ if ((self = [super init])) {
+ devToolsView_.reset([devToolsView retain]);
+ delegate_ = delegate;
+ }
+ return self;
+}
+
+- (void)updateDevToolsForTabContents:(TabContents*)contents {
+ // Get current devtools content.
+ TabContents* devToolsContents = contents ?
+ DevToolsWindow::GetDevToolsContents(contents) : NULL;
+
+ [self showDevToolsContents:devToolsContents];
+}
+
+- (void)showDevToolsContents:(TabContents*)devToolsContents {
+ NSArray* subviews = [devToolsView_ subviews];
+ if (devToolsContents) {
+ DCHECK_GE([subviews count], 1u);
+
+ // |devToolsView| is a TabContentsViewCocoa object, whose ViewID was
+ // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
+ // VIEW_ID_DEV_TOOLS_DOCKED here.
+ NSView* devToolsView = devToolsContents->GetNativeView();
+ view_id_util::SetID(devToolsView, VIEW_ID_DEV_TOOLS_DOCKED);
+
+ CGFloat splitOffset = 0;
+ if ([subviews count] == 1) {
+ // Load the default split offset.
+ splitOffset = g_browser_process->local_state()->GetInteger(
+ prefs::kDevToolsSplitLocation);
+ if (splitOffset < 0) {
+ // Initial load, set to default value.
+ splitOffset = kDefaultContentsSplitOffset;
+ }
+ [devToolsView_ addSubview:devToolsView];
+ } else {
+ DCHECK_EQ([subviews count], 2u);
+ // If devtools are already visible, keep the current size.
+ splitOffset = NSHeight([devToolsView frame]);
+ [devToolsView_ replaceSubview:[subviews objectAtIndex:1]
+ with:devToolsView];
+ }
+
+ // Make sure |splitOffset| isn't too large or too small.
+ splitOffset =
+ std::min(splitOffset, NSHeight([devToolsView_ frame]) - kMinWebHeight);
+ DCHECK_GE(splitOffset, 0) << "kMinWebHeight needs to be smaller than "
+ << "smallest available tab contents space.";
+ splitOffset = std::max(static_cast<CGFloat>(0), splitOffset);
+
+ [delegate_ resizeDevToolsToNewHeight:splitOffset];
+ } else {
+ if ([subviews count] > 1) {
+ NSView* oldDevToolsContentsView = [subviews objectAtIndex:1];
+ // Store split offset when hiding devtools window only.
+ int splitOffset = NSHeight([oldDevToolsContentsView frame]);
+ g_browser_process->local_state()->SetInteger(
+ prefs::kDevToolsSplitLocation, splitOffset);
+ [oldDevToolsContentsView removeFromSuperview];
+ }
+ }
+}
+
+@end
diff --git a/chrome/browser/cocoa/infobar_container_controller.h b/chrome/browser/cocoa/infobar_container_controller.h
index 81e82f4..495b6e8 100644
--- a/chrome/browser/cocoa/infobar_container_controller.h
+++ b/chrome/browser/cocoa/infobar_container_controller.h
@@ -2,6 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#ifndef CHROME_BROWSER_COCOA_INFOBAR_CONTAINER_CONTROLLER_H_
+#define CHROME_BROWSER_COCOA_INFOBAR_CONTAINER_CONTROLLER_H_
+#pragma once
+
#import <Cocoa/Cocoa.h>
#include "base/scoped_nsobject.h"
@@ -14,7 +18,6 @@ class InfoBarDelegate;
class InfoBarNotificationObserver;
class TabContents;
class TabStripModel;
-class TabStripModelObserverBridge;
// Protocol for basic container methods, as needed by an InfoBarController.
// This protocol exists to make mocking easier in unittests.
@@ -40,9 +43,6 @@ class TabStripModelObserverBridge;
// Holds the InfoBarControllers currently owned by this container.
scoped_nsobject<NSMutableArray> infobarControllers_;
- // Lets us get TabChanged/TabDetachedAt notifications.
- scoped_ptr<TabStripModelObserverBridge> tabObserver_;
-
// Lets us registers for INFOBAR_ADDED/INFOBAR_REMOVED
// notifications. The actual notifications are sent to the
// InfoBarNotificationObserver object, which proxies them back to us.
@@ -50,8 +50,7 @@ class TabStripModelObserverBridge;
scoped_ptr<InfoBarNotificationObserver> infoBarObserver_;
}
-- (id)initWithTabStripModel:(TabStripModel*)model
- resizeDelegate:(id<ViewResizer>)resizeDelegate;
+- (id)initWithResizeDelegate:(id<ViewResizer>)resizeDelegate;
// Informs the selected TabContents that the infobars for the given
// |delegate| need to be removed. Does not remove any infobar views
@@ -65,6 +64,19 @@ class TabStripModelObserverBridge;
// |controller| is still on the call stack.
- (void)removeController:(InfoBarController*)controller;
+// Modifies this container to display infobars for the given
+// |contents|. Registers for INFOBAR_ADDED and INFOBAR_REMOVED
+// notifications for |contents|. If we are currently showing any
+// infobars, removes them first and deregisters for any
+// notifications. |contents| can be NULL, in which case no infobars
+// are shown and no notifications are registered for.
+- (void)changeTabContents:(TabContents*)contents;
+
+// Stripped down version of TabStripModelObserverBridge:tabDetachedWithContents.
+// Forwarded by BWC. Removes all infobars and deregisters for any notifications
+// if |contents| is the current tab contents.
+- (void)tabDetachedWithContents:(TabContents*)contents;
+
@end
@@ -97,3 +109,5 @@ class TabStripModelObserverBridge;
- (void)removeAllInfoBars;
@end
+
+#endif // CHROME_BROWSER_COCOA_INFOBAR_CONTAINER_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/infobar_container_controller.mm b/chrome/browser/cocoa/infobar_container_controller.mm
index 374d920..7fe8aed 100644
--- a/chrome/browser/cocoa/infobar_container_controller.mm
+++ b/chrome/browser/cocoa/infobar_container_controller.mm
@@ -8,7 +8,6 @@
#include "chrome/browser/cocoa/infobar.h"
#import "chrome/browser/cocoa/infobar_container_controller.h"
#import "chrome/browser/cocoa/infobar_controller.h"
-#include "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
#import "chrome/browser/cocoa/view_id_util.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
@@ -64,25 +63,15 @@ class InfoBarNotificationObserver : public NotificationObserver {
// adding together the heights of all its subviews.
- (CGFloat)desiredHeight;
-// Modifies this container to display infobars for the given
-// |contents|. Registers for INFOBAR_ADDED and INFOBAR_REMOVED
-// notifications for |contents|. If we are currently showing any
-// infobars, removes them first and deregisters for any
-// notifications. |contents| can be NULL, in which case no infobars
-// are shown and no notifications are registered for.
-- (void)changeTabContents:(TabContents*)contents;
-
@end
@implementation InfoBarContainerController
-- (id)initWithTabStripModel:(TabStripModel*)model
- resizeDelegate:(id<ViewResizer>)resizeDelegate {
+- (id)initWithResizeDelegate:(id<ViewResizer>)resizeDelegate {
DCHECK(resizeDelegate);
if ((self = [super initWithNibName:@"InfoBarContainer"
bundle:mac_util::MainAppBundle()])) {
resizeDelegate_ = resizeDelegate;
- tabObserver_.reset(new TabStripModelObserverBridge(model, self));
infoBarObserver_.reset(new InfoBarNotificationObserver(self));
// NSMutableArray needs an initial capacity, and we rarely ever see
@@ -122,16 +111,30 @@ class InfoBarNotificationObserver : public NotificationObserver {
[self positionInfoBarsAndRedraw];
}
-// TabStripModelObserverBridge notifications
-- (void)selectTabWithContents:(TabContents*)newContents
- previousContents:(TabContents*)oldContents
- atIndex:(NSInteger)index
- userGesture:(bool)wasUserGesture {
- [self changeTabContents:newContents];
+- (void)changeTabContents:(TabContents*)contents {
+ registrar_.RemoveAll();
+ [self removeAllInfoBars];
+
+ currentTabContents_ = contents;
+ if (currentTabContents_) {
+ for (int i = 0; i < currentTabContents_->infobar_delegate_count(); ++i) {
+ [self addInfoBar:currentTabContents_->GetInfoBarDelegateAt(i)
+ animate:NO];
+ }
+
+ Source<TabContents> source(currentTabContents_);
+ registrar_.Add(infoBarObserver_.get(),
+ NotificationType::TAB_CONTENTS_INFOBAR_ADDED, source);
+ registrar_.Add(infoBarObserver_.get(),
+ NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, source);
+ registrar_.Add(infoBarObserver_.get(),
+ NotificationType::TAB_CONTENTS_INFOBAR_REPLACED, source);
+ }
+
+ [self positionInfoBarsAndRedraw];
}
-- (void)tabDetachedWithContents:(TabContents*)contents
- atIndex:(NSInteger)index {
+- (void)tabDetachedWithContents:(TabContents*)contents {
if (currentTabContents_ == contents)
[self changeTabContents:NULL];
}
@@ -159,29 +162,6 @@ class InfoBarNotificationObserver : public NotificationObserver {
return height;
}
-- (void)changeTabContents:(TabContents*)contents {
- registrar_.RemoveAll();
- [self removeAllInfoBars];
-
- currentTabContents_ = contents;
- if (currentTabContents_) {
- for (int i = 0; i < currentTabContents_->infobar_delegate_count(); ++i) {
- [self addInfoBar:currentTabContents_->GetInfoBarDelegateAt(i)
- animate:NO];
- }
-
- Source<TabContents> source(currentTabContents_);
- registrar_.Add(infoBarObserver_.get(),
- NotificationType::TAB_CONTENTS_INFOBAR_ADDED, source);
- registrar_.Add(infoBarObserver_.get(),
- NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, source);
- registrar_.Add(infoBarObserver_.get(),
- NotificationType::TAB_CONTENTS_INFOBAR_REPLACED, source);
- }
-
- [self positionInfoBarsAndRedraw];
-}
-
- (void)addInfoBar:(InfoBarDelegate*)delegate animate:(BOOL)animate {
scoped_ptr<InfoBar> infobar(delegate->CreateInfoBar());
InfoBarController* controller = infobar->controller();
diff --git a/chrome/browser/cocoa/infobar_container_controller_unittest.mm b/chrome/browser/cocoa/infobar_container_controller_unittest.mm
index 569ed72..b9f74c7 100644
--- a/chrome/browser/cocoa/infobar_container_controller_unittest.mm
+++ b/chrome/browser/cocoa/infobar_container_controller_unittest.mm
@@ -5,7 +5,6 @@
#import <Cocoa/Cocoa.h>
#include "base/scoped_nsobject.h"
-#include "chrome/browser/cocoa/browser_test_helper.h"
#import "chrome/browser/cocoa/cocoa_test_helper.h"
#import "chrome/browser/cocoa/infobar_container_controller.h"
#include "chrome/browser/cocoa/infobar_test_helper.h"
@@ -19,11 +18,9 @@ class InfoBarContainerControllerTest : public CocoaTest {
virtual void SetUp() {
CocoaTest::SetUp();
resizeDelegate_.reset([[ViewResizerPong alloc] init]);
- TabStripModel* model = browser_helper_.browser()->tabstrip_model();
ViewResizerPong *viewResizer = resizeDelegate_.get();
controller_ =
- [[InfoBarContainerController alloc] initWithTabStripModel:model
- resizeDelegate:viewResizer];
+ [[InfoBarContainerController alloc] initWithResizeDelegate:viewResizer];
NSView* view = [controller_ view];
[[test_window() contentView] addSubview:view];
}
@@ -35,7 +32,6 @@ class InfoBarContainerControllerTest : public CocoaTest {
}
public:
- BrowserTestHelper browser_helper_;
scoped_nsobject<ViewResizerPong> resizeDelegate_;
InfoBarContainerController* controller_;
};
diff --git a/chrome/browser/cocoa/side_tab_strip_controller.mm b/chrome/browser/cocoa/side_tab_strip_controller.mm
index 0f59329..9ff73d1 100644
--- a/chrome/browser/cocoa/side_tab_strip_controller.mm
+++ b/chrome/browser/cocoa/side_tab_strip_controller.mm
@@ -14,8 +14,12 @@
- (id)initWithView:(TabStripView*)view
switchView:(NSView*)switchView
- browser:(Browser*)browser {
- self = [super initWithView:view switchView:switchView browser:browser];
+ browser:(Browser*)browser
+ delegate:(id<TabStripControllerDelegate>)delegate {
+ self = [super initWithView:view
+ switchView:switchView
+ browser:browser
+ delegate:delegate];
if (self) {
// Side tabs have no indent since they are not sharing space with the
// window controls.
diff --git a/chrome/browser/cocoa/sidebar_controller.h b/chrome/browser/cocoa/sidebar_controller.h
new file mode 100644
index 0000000..c6bdfc6
--- /dev/null
+++ b/chrome/browser/cocoa/sidebar_controller.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2010 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_COCOA_SIDEBAR_CONTROLLER_H_
+#define CHROME_BROWSER_COCOA_SIDEBAR_CONTROLLER_H_
+#pragma once
+
+#import <Foundation/Foundation.h>
+
+#include "base/scoped_nsobject.h"
+
+@class NSSplitView;
+@class NSView;
+
+class TabContents;
+
+// Sidebar controller's delegate interface. Delegate is responsible
+// for the actual subviews resize and layout.
+@protocol SidebarControllerDelegate
+
+// Resizes the sidebar view to the new |width| and adjusts window layout
+// accordingly.
+- (void)resizeSidebarToNewWidth:(CGFloat)width;
+
+@end
+
+// A class that handles updates of the sidebar view within a browser window.
+// It swaps in the relevant sidebar contents for a given TabContents or removes
+// the vew, if there's no sidebar contents to show.
+@interface SidebarController : NSObject {
+ @private
+ // A view hosting sidebar contents.
+ scoped_nsobject<NSSplitView> sidebarView_;
+ id<SidebarControllerDelegate> delegate_; // weak
+ // Currently displayed sidebar contents.
+ TabContents* sidebarContents_; // weak.
+}
+
+- (id)initWithView:(NSSplitView*)sidebarView
+ delegate:(id<SidebarControllerDelegate>)delegate;
+
+// Depending on |contents|'s state, decides whether the sidebar
+// should be shown or hidden and adjusts its width (|delegate_| handles
+// the actual resize).
+- (void)updateSidebarForTabContents:(TabContents*)contents;
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_SIDEBAR_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/sidebar_controller.mm b/chrome/browser/cocoa/sidebar_controller.mm
new file mode 100644
index 0000000..1855358
--- /dev/null
+++ b/chrome/browser/cocoa/sidebar_controller.mm
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 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.
+
+#import "chrome/browser/cocoa/sidebar_controller.h"
+
+#include <algorithm>
+
+#include <Cocoa/Cocoa.h>
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_process.h"
+#import "chrome/browser/cocoa/view_id_util.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/sidebar/sidebar_manager.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/pref_names.h"
+
+namespace {
+
+// By default sidebar width is 1/7th of the current page content width.
+const CGFloat kDefaultSidebarWidthRatio = 1.0 / 7;
+
+// Never make the web part of the tab contents smaller than this (needed if the
+// window is only a few pixels wide).
+const int kMinWebWidth = 50;
+
+} // end namespace
+
+
+@interface SidebarController (Private)
+- (void)showSidebarContents:(TabContents*)sidebarContents;
+@end
+
+
+@implementation SidebarController
+
+- (id)initWithView:(NSSplitView*)sidebarView
+ delegate:(id<SidebarControllerDelegate>)delegate {
+ DCHECK(delegate);
+ if ((self = [super init])) {
+ sidebarView_.reset([sidebarView retain]);
+ delegate_ = delegate;
+ sidebarContents_ = NULL;
+ }
+ return self;
+}
+
+- (void)updateSidebarForTabContents:(TabContents*)contents {
+ // Get the active sidebar content.
+ if (SidebarManager::GetInstance() == NULL) // Happens in tests.
+ return;
+
+ TabContents* sidebarContents = NULL;
+ if (contents && SidebarManager::IsSidebarAllowed()) {
+ SidebarContainer* activeSidebar =
+ SidebarManager::GetInstance()->GetActiveSidebarContainerFor(contents);
+ if (activeSidebar)
+ sidebarContents = activeSidebar->sidebar_contents();
+ }
+ if (sidebarContents_ == sidebarContents)
+ return;
+
+ TabContents* oldSidebarContents = sidebarContents_;
+ sidebarContents_ = sidebarContents;
+
+ // Adjust sidebar view.
+ [self showSidebarContents:sidebarContents];
+
+ // Notify extensions.
+ SidebarManager::GetInstance()->NotifyStateChanges(
+ oldSidebarContents, sidebarContents);
+}
+
+- (void)showSidebarContents:(TabContents*)sidebarContents {
+ NSArray* subviews = [sidebarView_ subviews];
+ if (sidebarContents) {
+ DCHECK_GE([subviews count], 1u);
+
+ // |sidebarView| is a TabContentsViewCocoa object, whose ViewID was
+ // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
+ // VIEW_ID_SIDE_BAR_CONTAINER here.
+ NSView* sidebarView = sidebarContents->GetNativeView();
+ view_id_util::SetID(sidebarView, VIEW_ID_SIDE_BAR_CONTAINER);
+
+ CGFloat sidebarWidth = 0;
+ if ([subviews count] == 1) {
+ // Load the default split offset.
+ sidebarWidth = g_browser_process->local_state()->GetInteger(
+ prefs::kExtensionSidebarWidth);
+ if (sidebarWidth < 0) {
+ // Initial load, set to default value.
+ sidebarWidth =
+ NSWidth([sidebarView_ frame]) * kDefaultSidebarWidthRatio;
+ }
+ [sidebarView_ addSubview:sidebarView];
+ } else {
+ DCHECK_EQ([subviews count], 2u);
+ sidebarWidth = NSWidth([[subviews objectAtIndex:1] frame]);
+ [sidebarView_ replaceSubview:[subviews objectAtIndex:1]
+ with:sidebarView];
+ }
+
+ // Make sure |sidebarWidth| isn't too large or too small.
+ sidebarWidth = std::min(sidebarWidth,
+ NSWidth([sidebarView_ frame]) - kMinWebWidth);
+ DCHECK_GE(sidebarWidth, 0) << "kMinWebWidth needs to be smaller than "
+ << "smallest available tab contents space.";
+ sidebarWidth = std::max(static_cast<CGFloat>(0), sidebarWidth);
+
+ [delegate_ resizeSidebarToNewWidth:sidebarWidth];
+ } else {
+ if ([subviews count] > 1) {
+ NSView* oldSidebarContentsView = [subviews objectAtIndex:1];
+ // Store split offset when hiding sidebar window only.
+ int sidebarWidth = NSWidth([oldSidebarContentsView frame]);
+ g_browser_process->local_state()->SetInteger(
+ prefs::kExtensionSidebarWidth, sidebarWidth);
+ [oldSidebarContentsView removeFromSuperview];
+ }
+ }
+}
+
+@end
diff --git a/chrome/browser/cocoa/tab_contents_controller.h b/chrome/browser/cocoa/tab_contents_controller.h
index ce156c0..64a60cc 100644
--- a/chrome/browser/cocoa/tab_contents_controller.h
+++ b/chrome/browser/cocoa/tab_contents_controller.h
@@ -9,26 +9,19 @@
#include <Cocoa/Cocoa.h>
class TabContents;
-class TabContentsCommandObserver;
-class TabStripModel;
// A class that controls the web contents of a tab. It manages displaying the
-// native view for a given TabContents and optionally its docked devtools in
-// |contentsContainer_|.
-// Note that just creating the class does not display the view in
-// |contentsContainer_|. We defer inserting it until the box is the correct size
-// to avoid multiple resize messages to the renderer. You must call
-// |-ensureContentsVisible| to display the render widget host view.
+// native view for a given TabContents.
+// Note that just creating the class does not display the view. We defer
+// inserting it until the box is the correct size to avoid multiple resize
+// messages to the renderer. You must call |-ensureContentsVisible| to display
+// the render widget host view.
@interface TabContentsController : NSViewController {
@private
- TabContentsCommandObserver* observer_; // nil if |commands_| is nil
TabContents* contents_; // weak
- TabContents* sidebarContents_; // weak
-
- IBOutlet NSSplitView* contentsContainer_;
- IBOutlet NSSplitView* devToolsContainer_;
}
+@property(readonly, nonatomic) TabContents* tabContents;
// Create the contents of a tab represented by |contents| and loaded from the
// nib given by |name|.
@@ -44,6 +37,10 @@ class TabStripModel;
// enabled.
- (void)willBecomeSelectedTab;
+// Call when the tab contents is about to be replaced with the currently
+// selected tab contents to do not trigger unnecessary content relayout.
+- (void)ensureContentsSizeDoesNotChange;
+
// Call when the tab view is properly sized and the render widget host view
// should be put into the view hierarchy.
- (void)ensureContentsVisible;
@@ -53,26 +50,6 @@ class TabStripModel;
// an entirely new tab contents object.
- (void)tabDidChange:(TabContents*)updatedContents;
-// Shows |devToolsContents| in a split view, or removes the bottom view in the
-// split viewif |devToolsContents| is NULL.
-// TODO(thakis): Either move this to tab_window or move infobar handling to here
-// too -- http://crbug.com/31633 .
-- (void)showDevToolsContents:(TabContents*)devToolsContents;
-
-// Returns the height required by devtools and divider, or 0 if no devtools are
-// docked to the tab.
-- (CGFloat)devToolsHeight;
-
-// Shows |sidebarContents| in a split view, or removes the right view in the
-// split view if |sidebarContents| is NULL.
-// TODO(thakis): Either move this to tab_window or move infobar handling to here
-// too -- http://crbug.com/31633 .
-- (void)showSidebarContents:(TabContents*)sidebarContents;
-
-// Returns contents of the currently displayed sidebar; returns NULL if there
-// isn't any.
-- (TabContents*)sidebarContents;
-
@end
#endif // CHROME_BROWSER_COCOA_TAB_CONTENTS_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/tab_contents_controller.mm b/chrome/browser/cocoa/tab_contents_controller.mm
index 545d6f1..ac0c8c2 100644
--- a/chrome/browser/cocoa/tab_contents_controller.mm
+++ b/chrome/browser/cocoa/tab_contents_controller.mm
@@ -5,26 +5,13 @@
#import "chrome/browser/cocoa/tab_contents_controller.h"
#include "base/mac_util.h"
-#include "base/sys_string_conversions.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/view_id_util.h"
-#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/common/pref_names.h"
-
-// Default offset of the contents splitter in pixels.
-static const int kDefaultContentsSplitOffset = 400;
-
-// Never make the web part of the tab contents smaller than this (needed if the
-// window is only a few pixels high/wide).
-const int kMinWebHeight = 50;
-const int kMinWebWidth = 50;
@implementation TabContentsController
+@synthesize tabContents = contents_;
- (id)initWithNibName:(NSString*)name
contents:(TabContents*)contents {
@@ -32,7 +19,6 @@ const int kMinWebWidth = 50;
bundle:mac_util::MainAppBundle()])) {
contents_ = contents;
}
- sidebarContents_ = NULL;
return self;
}
@@ -42,15 +28,28 @@ const int kMinWebWidth = 50;
[super dealloc];
}
+- (void)ensureContentsSizeDoesNotChange {
+ NSView* contentsContainer = [self view];
+ NSArray* subviews = [contentsContainer subviews];
+ if ([subviews count] > 0)
+ [contents_->GetNativeView() setAutoresizingMask:NSViewNotSizable];
+}
+
// Call when the tab view is properly sized and the render widget host view
// should be put into the view hierarchy.
- (void)ensureContentsVisible {
- NSArray* subviews = [contentsContainer_ subviews];
- if ([subviews count] == 0)
- [contentsContainer_ addSubview:contents_->GetNativeView()];
- else if ([subviews objectAtIndex:0] != contents_->GetNativeView())
- [contentsContainer_ replaceSubview:[subviews objectAtIndex:0]
- with:contents_->GetNativeView()];
+ NSView* contentsContainer = [self view];
+ NSArray* subviews = [contentsContainer subviews];
+ NSView* contentsNativeView = contents_->GetNativeView();
+ [contentsNativeView setFrame:[contentsContainer frame]];
+ if ([subviews count] == 0) {
+ [contentsContainer addSubview:contentsNativeView];
+ } else if ([subviews objectAtIndex:0] != contentsNativeView) {
+ [contentsContainer replaceSubview:[subviews objectAtIndex:0]
+ with:contentsNativeView];
+ }
+ [contentsNativeView setAutoresizingMask:NSViewWidthSizable|
+ NSViewHeightSizable];
}
// Returns YES if the tab represented by this controller is the front-most.
@@ -85,138 +84,4 @@ const int kMinWebWidth = 50;
}
}
-- (void)showDevToolsContents:(TabContents*)devToolsContents {
- NSArray* subviews = [devToolsContainer_ subviews];
- if (devToolsContents) {
- DCHECK_GE([subviews count], 1u);
-
- // Load the default split offset. If we are already showing devtools, we
- // will replace the default with the current devtools height.
- CGFloat splitOffset = g_browser_process->local_state()->GetInteger(
- prefs::kDevToolsSplitLocation);
- if (splitOffset == -1) {
- // Initial load, set to default value.
- splitOffset = kDefaultContentsSplitOffset;
- }
-
- // |devtoolsView| is a TabContentsViewCocoa object, whose ViewID was
- // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
- // VIEW_ID_DEV_TOOLS_DOCKED here.
- NSView* devtoolsView = devToolsContents->GetNativeView();
- view_id_util::SetID(devtoolsView, VIEW_ID_DEV_TOOLS_DOCKED);
- if ([subviews count] == 1) {
- [devToolsContainer_ addSubview:devtoolsView];
- } else {
- DCHECK_EQ([subviews count], 2u);
- [devToolsContainer_ replaceSubview:[subviews objectAtIndex:1]
- with:devToolsContents->GetNativeView()];
- // If devtools are already visible, keep the current size.
- splitOffset = NSHeight([devtoolsView frame]);
- }
-
- // Make sure |splitOffset| isn't too large or too small.
- splitOffset = MIN(splitOffset,
- NSHeight([devToolsContainer_ frame]) - kMinWebHeight);
- DCHECK_GE(splitOffset, 0) << "kMinWebHeight needs to be smaller than "
- << "smallest available tab contents space.";
- splitOffset = MAX(0, splitOffset);
-
- // It seems as if |-setPosition:ofDividerAtIndex:| should do what's needed,
- // but I can't figure out how to use it. Manually resize web and devtools.
- NSRect devtoolsFrame = [devtoolsView frame];
- devtoolsFrame.size.height = splitOffset;
- [devtoolsView setFrame:devtoolsFrame];
-
- NSRect webFrame = [[subviews objectAtIndex:0] frame];
- webFrame.size.height = NSHeight([devToolsContainer_ frame]) -
- [self devToolsHeight];
- [[subviews objectAtIndex:0] setFrame:webFrame];
-
- [devToolsContainer_ adjustSubviews];
- } else {
- if ([subviews count] > 1) {
- NSView* oldDevToolsContentsView = [subviews objectAtIndex:1];
- // Store split offset when hiding devtools window only.
- int splitOffset = NSHeight([oldDevToolsContentsView frame]);
- g_browser_process->local_state()->SetInteger(
- prefs::kDevToolsSplitLocation, splitOffset);
- [oldDevToolsContentsView removeFromSuperview];
- }
- }
-}
-
-- (CGFloat)devToolsHeight {
- NSArray* subviews = [devToolsContainer_ subviews];
- if ([subviews count] < 2)
- return 0;
- return NSHeight([[subviews objectAtIndex:1] frame]) +
- [devToolsContainer_ dividerThickness];
-}
-
-// This function is very similar to showDevToolsContents.
-// TODO(alekseys): refactor and move both to browser window.
-// I (alekseys) intend to do it very soon.
-- (void)showSidebarContents:(TabContents*)sidebarContents {
- sidebarContents_ = sidebarContents;
- NSArray* subviews = [contentsContainer_ subviews];
- if (sidebarContents) {
- DCHECK_GE([subviews count], 1u);
-
- // Load the default split offset.
- CGFloat sidebarWidth = g_browser_process->local_state()->GetInteger(
- prefs::kExtensionSidebarWidth);
- if (sidebarWidth == -1) {
- // Initial load, set to default value.
- sidebarWidth = NSWidth([contentsContainer_ frame]) / 7;
- }
-
- // |sidebarView| is a TabContentsViewCocoa object, whose ViewID was
- // set to VIEW_ID_TAB_CONTAINER initially, so we need to change it to
- // VIEW_ID_SIDE_BAR_CONTAINER here.
- NSView* sidebarView = sidebarContents->GetNativeView();
- view_id_util::SetID(sidebarView, VIEW_ID_SIDE_BAR_CONTAINER);
- if ([subviews count] == 1) {
- [contentsContainer_ addSubview:sidebarView];
- } else {
- DCHECK_EQ([subviews count], 2u);
- sidebarWidth = NSWidth([[subviews objectAtIndex:1] frame]);
- [contentsContainer_ replaceSubview:[subviews objectAtIndex:1]
- with:sidebarContents->GetNativeView()];
- }
-
- // Make sure |sidebarWidth| isn't too large or too small.
- sidebarWidth = MIN(sidebarWidth,
- NSWidth([contentsContainer_ frame]) - kMinWebWidth);
- DCHECK_GE(sidebarWidth, 0) << "kMinWebWidth needs to be smaller than "
- << "smallest available tab contents space.";
- sidebarWidth = MAX(0, sidebarWidth);
-
- // It seems as if |-setPosition:ofDividerAtIndex:| should do what's needed,
- // but I can't figure out how to use it. Manually resize web and sidebar.
- NSRect sidebarFrame = [sidebarView frame];
- sidebarFrame.size.width = sidebarWidth;
- [sidebarView setFrame:sidebarFrame];
-
- NSRect webFrame = [[subviews objectAtIndex:0] frame];
- webFrame.size.width = NSWidth([contentsContainer_ frame]) -
- ([contentsContainer_ dividerThickness] + sidebarWidth);
- [[subviews objectAtIndex:0] setFrame:webFrame];
-
- [contentsContainer_ adjustSubviews];
- } else {
- if ([subviews count] > 1) {
- NSView* oldSidebarContentsView = [subviews objectAtIndex:1];
- // Store split offset when hiding sidebar window only.
- int sidebarWidth = NSWidth([oldSidebarContentsView frame]);
- g_browser_process->local_state()->SetInteger(
- prefs::kExtensionSidebarWidth, sidebarWidth);
- [oldSidebarContentsView removeFromSuperview];
- }
- }
-}
-
-- (TabContents*)sidebarContents {
- return sidebarContents_;
-}
-
@end
diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h
index e03267b..170d3ac 100644
--- a/chrome/browser/cocoa/tab_strip_controller.h
+++ b/chrome/browser/cocoa/tab_strip_controller.h
@@ -26,6 +26,26 @@ class TabStripModel;
class TabContents;
class ToolbarModel;
+// The interface for the tab strip controller's delegate. Currently, the
+// delegate is the BWC and is responsible for subviews layout and forwarding
+// these events to InfoBarContainerController.
+// Delegating TabStripModelObserverBridge's events (in lieu of subscrining
+// BWC and InfoBarContainerController to TabStripModelObserverBridge events)
+// is necessary to guarantee a proper order of subviews layout updates,
+// otherwise it might trigger unnesessary content relayout, UI flickering etc.
+@protocol TabStripControllerDelegate
+
+// Stripped down version of TabStripModelObserverBridge:selectTabWithContents.
+- (void)onSelectTabWithContents:(TabContents*)contents;
+
+// Stripped down version of TabStripModelObserverBridge:tabChangedWithContents.
+- (void)onSelectedTabChange:(TabStripModelObserver::TabChangeType)change;
+
+// Stripped down version of TabStripModelObserverBridge:tabDetachedWithContents.
+- (void)onTabDetachedWithContents:(TabContents*)contents;
+
+@end
+
// A class that handles managing the tab strip in a browser window. It uses
// a supporting C++ bridge object to register for notifications from the
// TabStripModel. The Obj-C part of this class handles drag and drop and all
@@ -52,6 +72,8 @@ class ToolbarModel;
scoped_ptr<TabStripModelObserverBridge> bridge_;
Browser* browser_; // weak
TabStripModel* tabStripModel_; // weak
+ // Delegate that is informed about tab state changes.
+ id<TabStripControllerDelegate> delegate_; // weak
// YES if the new tab button is currently displaying the hover image (if the
// mouse is currently over the button).
@@ -126,9 +148,12 @@ class ToolbarModel;
// "switched" every time the user switches tabs. The children of this view
// will be released, so if you want them to stay around, make sure
// you have retained them.
+// |delegate| is the one listening to filtered TabStripModelObserverBridge's
+// events (see TabStripControllerDelegate for more details).
- (id)initWithView:(TabStripView*)view
switchView:(NSView*)switchView
- browser:(Browser*)browser;
+ browser:(Browser*)browser
+ delegate:(id<TabStripControllerDelegate>)delegate;
// Return the view for the currently selected tab.
- (NSView*)selectedTabView;
@@ -221,8 +246,6 @@ class ToolbarModel;
// functions.
- (void)attachConstrainedWindow:(ConstrainedWindowMac*)window;
- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window;
-- (void)updateDevToolsForContents:(TabContents*)contents;
-- (void)updateSidebarForContents:(TabContents*)contents;
@end
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
index 225b6d5..b3b19c0 100644
--- a/chrome/browser/cocoa/tab_strip_controller.mm
+++ b/chrome/browser/cocoa/tab_strip_controller.mm
@@ -279,13 +279,15 @@ private:
- (id)initWithView:(TabStripView*)view
switchView:(NSView*)switchView
- browser:(Browser*)browser {
- DCHECK(view && switchView && browser);
+ browser:(Browser*)browser
+ delegate:(id<TabStripControllerDelegate>)delegate {
+ DCHECK(view && switchView && browser && delegate);
if ((self = [super init])) {
tabStripView_.reset([view retain]);
switchView_ = switchView;
browser_ = browser;
tabStripModel_ = browser_->tabstrip_model();
+ delegate_ = delegate;
bridge_.reset(new TabStripModelObserverBridge(tabStripModel_, self));
tabContentsArray_.reset([[NSMutableArray alloc] init]);
tabArray_.reset([[NSMutableArray alloc] init]);
@@ -440,9 +442,10 @@ private:
// the view hierarchy. This is in order to avoid sending the renderer a
// spurious default size loaded from the nib during the call to |-view|.
NSView* newView = [controller view];
- NSRect frame = [switchView_ bounds];
- [newView setFrame:frame];
- [controller ensureContentsVisible];
+
+ // Turns content autoresizing off, so removing and inserting views won't
+ // trigger unnecessary content relayout.
+ [controller ensureContentsSizeDoesNotChange];
// Remove the old view from the view hierarchy. We know there's only one
// child of |switchView_| because we're the one who put it there. There
@@ -451,11 +454,22 @@ private:
NSArray* subviews = [switchView_ subviews];
if ([subviews count]) {
NSView* oldView = [subviews objectAtIndex:0];
+ // Set newView frame to the oldVew frame to prevent NSSplitView hosting
+ // sidebar and tab content from resizing sidebar's content view.
+ // ensureContentsVisible (see below) sets content size and autoresizing
+ // properties.
+ [newView setFrame:[oldView frame]];
[switchView_ replaceSubview:oldView with:newView];
} else {
[switchView_ addSubview:newView];
}
+ // New content is in place, delegate should adjust itself accordingly.
+ [delegate_ onSelectTabWithContents:[controller tabContents]];
+
+ // It also resores content autoresizing properties.
+ [controller ensureContentsVisible];
+
// Make sure the new tabs's sheets are visible (necessary when a background
// tab opened a sheet while it was in the background and now becomes active).
TabContents* newTab = tabStripModel_->GetTabContentsAt(modelIndex);
@@ -1048,8 +1062,6 @@ private:
// Swap in the contents for the new tab.
[self swapInTabAtIndex:modelIndex];
- [self updateSidebarForContents:newContents];
- [self updateDevToolsForContents:newContents];
if (newContents) {
newContents->DidBecomeSelected();
@@ -1155,14 +1167,12 @@ private:
[self removeTab:tab];
}
- // Does nothing, purely for consistency with the windows/linux code.
- [self updateSidebarForContents:NULL];
- [self updateDevToolsForContents:NULL];
-
// Send a broadcast that the number of tabs have changed.
[[NSNotificationCenter defaultCenter]
postNotificationName:kTabStripNumberOfTabsChanged
object:self];
+
+ [delegate_ onTabDetachedWithContents:contents];
}
// A helper routine for creating an NSImageView to hold the fav icon or app icon
@@ -1275,6 +1285,9 @@ private:
// Take closing tabs into account.
NSInteger index = [self indexFromModelIndex:modelIndex];
+ if (modelIndex == tabStripModel_->selected_index())
+ [delegate_ onSelectedTabChange:change];
+
if (change == TabStripModelObserver::TITLE_NOT_LOADING) {
// TODO(sky): make this work.
// We'll receive another notification of the change asynchronously.
@@ -1792,14 +1805,12 @@ private:
// View hierarchy of the contents view:
// NSView -- switchView, same for all tabs
- // +- NSView -- TabContentsController's view
- // +- NSSplitView
- // +- NSSplitView
- // +- TabContentsViewCocoa
+ // +- NSView -- TabContentsController's view
+ // +- TabContentsViewCocoa
+ // Changing it? Do not forget to modify removeConstrainedWindow too.
// We use the TabContentsController's view in |swapInTabAtIndex|, so we have
// to pass it to the sheet controller here.
- NSView* tabContentsView =
- [[[window->owner()->GetNativeView() superview] superview] superview];
+ NSView* tabContentsView = [window->owner()->GetNativeView() superview];
window->delegate()->RunSheet([self sheetController], tabContentsView);
// TODO(avi, thakis): GTMWindowSheetController has no api to move tabsheets
@@ -1817,8 +1828,7 @@ private:
}
- (void)removeConstrainedWindow:(ConstrainedWindowMac*)window {
- NSView* tabContentsView =
- [[[window->owner()->GetNativeView() superview] superview] superview];
+ NSView* tabContentsView = [window->owner()->GetNativeView() superview];
// TODO(avi, thakis): GTMWindowSheetController has no api to move tabsheets
// between windows. Until then, we have to prevent having to move a tabsheet
@@ -1833,58 +1843,4 @@ private:
}
}
-- (void)updateDevToolsForContents:(TabContents*)contents {
- int modelIndex = tabStripModel_->GetIndexOfTabContents(contents);
-
- // This happens e.g. if one hits cmd-q with a docked devtools window open.
- if (modelIndex == TabStripModel::kNoTab)
- return;
-
- NSInteger index = [self indexFromModelIndex:modelIndex];
- DCHECK_GE(index, 0);
- DCHECK_LT(index, (NSInteger)[tabContentsArray_ count]);
- if (index < 0 || index >= (NSInteger)[tabContentsArray_ count])
- return;
-
- TabContentsController* tabController =
- [tabContentsArray_ objectAtIndex:index];
- TabContents* devtoolsContents = contents ?
- DevToolsWindow::GetDevToolsContents(contents) : NULL;
- [tabController showDevToolsContents:devtoolsContents];
-}
-
-// This function is very similar to updateDevToolsContents.
-// TODO(alekseys): refactor and move both to browser window.
-// I (alekseys) intend to do it very soon.
-- (void)updateSidebarForContents:(TabContents*)contents {
- if (SidebarManager::GetInstance() == NULL) // Happens in tests.
- return;
-
- int modelIndex = tabStripModel_->GetIndexOfTabContents(contents);
-
- // This happens e.g. if one hits cmd-q with sidebar expanded.
- if (modelIndex == TabStripModel::kNoTab)
- return;
-
- NSInteger index = [self indexFromModelIndex:modelIndex];
- DCHECK_GE(index, 0);
- DCHECK_LT(index, (NSInteger)[tabContentsArray_ count]);
- if (index < 0 || index >= (NSInteger)[tabContentsArray_ count])
- return;
-
- TabContentsController* tabController =
- [tabContentsArray_ objectAtIndex:index];
- TabContents* sidebar_contents = NULL;
- if (contents && SidebarManager::IsSidebarAllowed()) {
- SidebarContainer* active_sidebar =
- SidebarManager::GetInstance()->GetActiveSidebarContainerFor(contents);
- if (active_sidebar)
- sidebar_contents = active_sidebar->sidebar_contents();
- }
- TabContents* old_sidebar_contents = [tabController sidebarContents];
- [tabController showSidebarContents:sidebar_contents];
- SidebarManager::GetInstance()->NotifyStateChanges(
- old_sidebar_contents, sidebar_contents);
-}
-
@end
diff --git a/chrome/browser/cocoa/tab_strip_controller_unittest.mm b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
index eee7580..e879b3c 100644
--- a/chrome/browser/cocoa/tab_strip_controller_unittest.mm
+++ b/chrome/browser/cocoa/tab_strip_controller_unittest.mm
@@ -15,6 +15,20 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
+@interface TestTabStripControllerDelegate :
+ NSObject<TabStripControllerDelegate> {
+}
+@end
+
+@implementation TestTabStripControllerDelegate
+- (void)onSelectTabWithContents:(TabContents*)contents {
+}
+- (void)onSelectedTabChange:(TabStripModelObserver::TabChangeType)change {
+}
+- (void)onTabDetachedWithContents:(TabContents*)contents {
+}
+@end
+
namespace {
// Stub model delegate
@@ -104,10 +118,12 @@ class TabStripControllerTest : public CocoaTest {
delegate_.reset(new TestTabStripDelegate());
model_ = browser->tabstrip_model();
+ controller_delegate_.reset([TestTabStripControllerDelegate alloc]);
controller_.reset([[TabStripController alloc]
initWithView:static_cast<TabStripView*>(tab_strip.get())
switchView:switch_view.get()
- browser:browser]);
+ browser:browser
+ delegate:controller_delegate_.get()]);
}
virtual void TearDown() {
@@ -122,6 +138,7 @@ class TabStripControllerTest : public CocoaTest {
BrowserTestHelper browser_helper_;
scoped_ptr<TestTabStripDelegate> delegate_;
TabStripModel* model_;
+ scoped_nsobject<TestTabStripControllerDelegate> controller_delegate_;
scoped_nsobject<TabStripController> controller_;
};
diff --git a/chrome/browser/cocoa/tab_window_controller.h b/chrome/browser/cocoa/tab_window_controller.h
index c4bdf79..9d97fe1 100644
--- a/chrome/browser/cocoa/tab_window_controller.h
+++ b/chrome/browser/cocoa/tab_window_controller.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_TAB_WINDOW_CONTROLLER_H_
-#define CHROME_BROWSER_TAB_WINDOW_CONTROLLER_H_
+#ifndef CHROME_BROWSER_COCOA_TAB_WINDOW_CONTROLLER_H_
+#define CHROME_BROWSER_COCOA_TAB_WINDOW_CONTROLLER_H_
#pragma once
// A class acting as the Objective-C window controller for a window that has
@@ -39,6 +39,8 @@
@interface TabWindowController : NSWindowController<NSWindowDelegate> {
@private
IBOutlet FastResizeView* tabContentArea_;
+ IBOutlet NSSplitView* contentsContainer_;
+ IBOutlet NSSplitView* devToolsContainer_;
// TODO(pinkerton): Figure out a better way to initialize one or the other
// w/out needing both to be in the nib.
IBOutlet TabStripView* topTabStripView_;
@@ -57,6 +59,8 @@
}
@property(readonly, nonatomic) TabStripView* tabStripView;
@property(readonly, nonatomic) FastResizeView* tabContentArea;
+@property(readonly, nonatomic) NSSplitView* contentsContainer;
+@property(readonly, nonatomic) NSSplitView* devToolsContainer;
// Used during tab dragging to turn on/off the overlay window when a tab
// is torn off. If -deferPerformClose (below) is used, -removeOverlay will
@@ -174,4 +178,4 @@
- (void)layoutSubviews;
@end
-#endif // CHROME_BROWSER_TAB_WINDOW_CONTROLLER_H_
+#endif // CHROME_BROWSER_COCOA_TAB_WINDOW_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/tab_window_controller.mm b/chrome/browser/cocoa/tab_window_controller.mm
index 4e886eb..f9e390b 100644
--- a/chrome/browser/cocoa/tab_window_controller.mm
+++ b/chrome/browser/cocoa/tab_window_controller.mm
@@ -41,6 +41,8 @@
@implementation TabWindowController
@synthesize tabContentArea = tabContentArea_;
+@synthesize contentsContainer = contentsContainer_;
+@synthesize devToolsContainer = devToolsContainer_;
- (id)initWithWindow:(NSWindow*)window {
if ((self = [super initWithWindow:window]) != nil) {
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index dff0e57..d726c17 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -826,6 +826,8 @@
'browser/cocoa/custom_home_pages_model.mm',
'browser/cocoa/delayedmenu_button.h',
'browser/cocoa/delayedmenu_button.mm',
+ 'browser/cocoa/dev_tools_controller.h',
+ 'browser/cocoa/dev_tools_controller.mm',
'browser/cocoa/dock_icon.h',
'browser/cocoa/dock_icon.mm',
'browser/cocoa/download_item_button.h',
@@ -1042,6 +1044,8 @@
'browser/cocoa/side_tab_strip_controller.mm',
'browser/cocoa/side_tab_strip_view.h',
'browser/cocoa/side_tab_strip_view.mm',
+ 'browser/cocoa/sidebar_controller.h',
+ 'browser/cocoa/sidebar_controller.mm',
'browser/cocoa/simple_content_exceptions_window_controller.h',
'browser/cocoa/simple_content_exceptions_window_controller.mm',
'browser/cocoa/speech_input_window_controller.h',