summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/nibs/English.lproj/BrowserWindow.xib161
-rw-r--r--chrome/app/nibs/English.lproj/MainMenu.xib12
-rw-r--r--chrome/browser/browser.cc14
-rw-r--r--chrome/browser/browser.h4
-rw-r--r--chrome/browser/browser_window_controller.h2
-rw-r--r--chrome/browser/browser_window_controller.mm23
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.h40
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm283
-rw-r--r--chrome/chrome.xcodeproj/project.pbxproj16
-rw-r--r--chrome/common/temp_scaffolding_stubs.cc31
-rw-r--r--chrome/common/temp_scaffolding_stubs.h5
11 files changed, 397 insertions, 194 deletions
diff --git a/chrome/app/nibs/English.lproj/BrowserWindow.xib b/chrome/app/nibs/English.lproj/BrowserWindow.xib
index 9edaef9..bbc543d 100644
--- a/chrome/app/nibs/English.lproj/BrowserWindow.xib
+++ b/chrome/app/nibs/English.lproj/BrowserWindow.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">352.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="2"/>
+ <integer value="56"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -44,7 +44,7 @@
<nil key="NSViewClass"/>
<string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
<object class="NSView" key="NSWindowView" id="1006">
- <reference key="NSNextResponder"/>
+ <nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -94,7 +94,6 @@
</object>
</object>
<string key="NSFrameSize">{720, 578}</string>
- <reference key="NSSuperview"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
@@ -102,99 +101,8 @@
<object class="NSCustomView" id="1029219716">
<reference key="NSNextResponder"/>
<int key="NSvFlags">266</int>
- <object class="NSMutableArray" key="NSSubviews">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSButton" id="670573781">
- <reference key="NSNextResponder" ref="1029219716"/>
- <int key="NSvFlags">268</int>
- <string key="NSFrame">{{66, 0}, {160, 25}}</string>
- <reference key="NSSuperview" ref="1029219716"/>
- <reference key="NSWindow"/>
- <bool key="NSEnabled">YES</bool>
- <object class="NSButtonCell" key="NSCell" id="663358254">
- <int key="NSCellFlags">-2080244224</int>
- <int key="NSCellFlags2">0</int>
- <string key="NSContents">Gmail - Inbox</string>
- <object class="NSFont" key="NSSupport" id="842878087">
- <string key="NSName">LucidaGrande</string>
- <double key="NSSize">1.100000e+01</double>
- <int key="NSfFlags">16</int>
- </object>
- <reference key="NSControlView" ref="670573781"/>
- <int key="NSButtonFlags">-2034482945</int>
- <int key="NSButtonFlags2">134</int>
- <object class="NSCustomResource" key="NSNormalImage">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">gmail</string>
- </object>
- <string key="NSAlternateContents"/>
- <string key="NSKeyEquivalent"/>
- <int key="NSPeriodicDelay">400</int>
- <int key="NSPeriodicInterval">75</int>
- </object>
- </object>
- <object class="NSButton" id="186766461">
- <reference key="NSNextResponder" ref="1029219716"/>
- <int key="NSvFlags">268</int>
- <string key="NSFrame">{{208, 0}, {160, 25}}</string>
- <reference key="NSSuperview" ref="1029219716"/>
- <reference key="NSWindow"/>
- <bool key="NSEnabled">YES</bool>
- <object class="NSButtonCell" key="NSCell" id="60827425">
- <int key="NSCellFlags">67239424</int>
- <int key="NSCellFlags2">0</int>
- <string type="base64-UTF8" key="NSContents">R29vZ2xlIERvY3PCoMKgwqA</string>
- <reference key="NSSupport" ref="842878087"/>
- <reference key="NSControlView" ref="186766461"/>
- <int key="NSButtonFlags">-2034482945</int>
- <int key="NSButtonFlags2">134</int>
- <object class="NSCustomResource" key="NSNormalImage">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">docs</string>
- </object>
- <string key="NSAlternateContents"/>
- <string key="NSKeyEquivalent"/>
- <int key="NSPeriodicDelay">400</int>
- <int key="NSPeriodicInterval">75</int>
- </object>
- </object>
- <object class="NSImageView" id="1060129566">
- <reference key="NSNextResponder" ref="1029219716"/>
- <int key="NSvFlags">256</int>
- <object class="NSMutableSet" key="NSDragTypes">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSMutableArray" key="set.sortedObjects">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>Apple PDF pasteboard type</string>
- <string>Apple PICT pasteboard type</string>
- <string>Apple PNG pasteboard type</string>
- <string>NSFilenamesPboardType</string>
- <string>NeXT Encapsulated PostScript v1.2 pasteboard type</string>
- <string>NeXT TIFF v4.0 pasteboard type</string>
- </object>
- </object>
- <string key="NSFrame">{{362, -1}, {30, 26}}</string>
- <reference key="NSSuperview" ref="1029219716"/>
- <reference key="NSWindow"/>
- <bool key="NSEnabled">YES</bool>
- <object class="NSImageCell" key="NSCell" id="244315328">
- <int key="NSCellFlags">130560</int>
- <int key="NSCellFlags2">33554432</int>
- <object class="NSCustomResource" key="NSContents">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">newtab</string>
- </object>
- <int key="NSAlign">0</int>
- <int key="NSScale">0</int>
- <int key="NSStyle">0</int>
- <bool key="NSAnimates">YES</bool>
- </object>
- <bool key="NSEditable">YES</bool>
- </object>
- </object>
<string key="NSFrameSize">{483, 25}</string>
<reference key="NSSuperview"/>
- <reference key="NSWindow"/>
<string key="NSClassName">TabBarView</string>
</object>
</object>
@@ -292,55 +200,10 @@
<reference key="object" ref="1029219716"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="1060129566"/>
- <reference ref="186766461"/>
- <reference ref="670573781"/>
</object>
<reference key="parent" ref="1002"/>
<string key="objectName">TabBar</string>
</object>
- <object class="IBObjectRecord">
- <int key="objectID">57</int>
- <reference key="object" ref="1060129566"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="244315328"/>
- </object>
- <reference key="parent" ref="1029219716"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">58</int>
- <reference key="object" ref="186766461"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="60827425"/>
- </object>
- <reference key="parent" ref="1029219716"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">59</int>
- <reference key="object" ref="670573781"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="663358254"/>
- </object>
- <reference key="parent" ref="1029219716"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">60</int>
- <reference key="object" ref="663358254"/>
- <reference key="parent" ref="670573781"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">61</int>
- <reference key="object" ref="60827425"/>
- <reference key="parent" ref="186766461"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">62</int>
- <reference key="object" ref="244315328"/>
- <reference key="parent" ref="1060129566"/>
- </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -364,12 +227,6 @@
<string>55.IBPluginDependency</string>
<string>56.IBEditorWindowLastContentRect</string>
<string>56.IBPluginDependency</string>
- <string>58.IBPluginDependency</string>
- <string>59.IBPluginDependency</string>
- <string>60.CustomClassName</string>
- <string>60.IBPluginDependency</string>
- <string>61.CustomClassName</string>
- <string>61.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -393,12 +250,6 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{160, 204}, {483, 25}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>TabCell</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>TabCell</string>
- <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -471,14 +322,6 @@
<string key="minorKey">browser/cocoa/tab_bar_view.h</string>
</object>
</object>
- <object class="IBPartialClassDescription">
- <string key="className">TabCell</string>
- <string key="superclassName">NSButtonCell</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">browser/cocoa/tab_cell.h</string>
- </object>
- </object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
diff --git a/chrome/app/nibs/English.lproj/MainMenu.xib b/chrome/app/nibs/English.lproj/MainMenu.xib
index 21298c0..53e0eb1 100644
--- a/chrome/app/nibs/English.lproj/MainMenu.xib
+++ b/chrome/app/nibs/English.lproj/MainMenu.xib
@@ -8,7 +8,7 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="497"/>
+ <integer value="449"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1360,17 +1360,17 @@
<object class="IBActionConnection" key="connection">
<string key="label">commandDispatch:</string>
<reference key="source" ref="1014"/>
- <reference key="destination" ref="603924433"/>
+ <reference key="destination" ref="1063389418"/>
</object>
- <int key="connectionID">525</int>
+ <int key="connectionID">526</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">commandDispatch:</string>
<reference key="source" ref="1014"/>
- <reference key="destination" ref="1063389418"/>
+ <reference key="destination" ref="603924433"/>
</object>
- <int key="connectionID">526</int>
+ <int key="connectionID">527</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
@@ -2687,7 +2687,7 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">526</int>
+ <int key="maxID">527</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 145939c..1ad5d8b 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -457,6 +457,8 @@ void Browser::OnWindowClosing() {
CloseAllTabs();
}
+#endif // OS_WIN
+
///////////////////////////////////////////////////////////////////////////////
// Browser, Tab adding/showing functions:
@@ -482,6 +484,8 @@ TabContents* Browser::AddTabWithURL(
return contents;
}
+#if defined(OS_WIN)
+
TabContents* Browser::AddWebApplicationTab(Profile* profile,
WebApp* web_app,
bool lazy) {
@@ -665,8 +669,6 @@ void Browser::CloseWindow() {
window_->Close();
}
-#if defined(OS_WIN)
-
void Browser::NewTab() {
UserMetrics::RecordAction(L"NewTab", profile_);
if (type() == TYPE_NORMAL) {
@@ -710,6 +712,8 @@ void Browser::SelectLastTab() {
tabstrip_model_.SelectLastTab();
}
+#if defined(OS_WIN)
+
void Browser::DuplicateTab() {
UserMetrics::RecordAction(L"Duplicate", profile_);
DuplicateContentsAt(selected_index());
@@ -1111,6 +1115,7 @@ void Browser::ExecuteCommand(int id) {
NewProfileWindowByIndex(id - IDC_NEW_WINDOW_PROFILE_0); break;
#if defined(OS_WIN)
case IDC_CLOSE_WINDOW: CloseWindow(); break;
+#endif
case IDC_NEW_TAB: NewTab(); break;
case IDC_CLOSE_TAB: CloseTab(); break;
case IDC_SELECT_NEXT_TAB: SelectNextTab(); break;
@@ -1125,6 +1130,7 @@ void Browser::ExecuteCommand(int id) {
case IDC_SELECT_TAB_7: SelectNumberedTab(id - IDC_SELECT_TAB_0);
break;
case IDC_SELECT_LAST_TAB: SelectLastTab(); break;
+#if defined(OS_WIN)
case IDC_DUPLICATE_TAB: DuplicateTab(); break;
case IDC_RESTORE_TAB: RestoreTab(); break;
case IDC_SHOW_AS_TAB: ConvertPopupToTabbedBrowser(); break;
@@ -2381,6 +2387,8 @@ void Browser::ClearUnloadState(TabContents* tab) {
ProcessPendingTabs();
}
+#endif // OS_WIN
+
///////////////////////////////////////////////////////////////////////////////
// Browser, Assorted utility functions (private):
@@ -2392,6 +2400,8 @@ Browser* Browser::GetOrCreateTabbedBrowser() {
return browser;
}
+#if defined(OS_WIN)
+
void Browser::BuildPopupWindow(TabContents* source,
TabContents* new_contents,
const gfx::Rect& initial_pos) {
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index e9880bc..6e71de4 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -246,13 +246,13 @@ class Browser : public TabStripModelDelegate,
void NewIncognitoWindow();
void NewProfileWindowByIndex(int index);
void CloseWindow();
-#if defined(OS_WIN)
void NewTab();
void CloseTab();
void SelectNextTab();
void SelectPreviousTab();
void SelectNumberedTab(int index);
void SelectLastTab();
+#if defined(OS_WIN)
void DuplicateTab();
void RestoreTab();
void ConvertPopupToTabbedBrowser();
@@ -504,6 +504,7 @@ class Browser : public TabStripModelDelegate,
// cases where a tab crashes or hangs even if the beforeunload/unload haven't
// successfully fired.
void ClearUnloadState(TabContents* tab);
+#endif
// Assorted utility functions ///////////////////////////////////////////////
@@ -511,6 +512,7 @@ class Browser : public TabStripModelDelegate,
// receiving Browser. Creates a new Browser if none are available.
Browser* GetOrCreateTabbedBrowser();
+#if defined(OS_WIN)
// Creates a new popup window with its own Browser object with the
// incoming sizing information. |initial_pos|'s origin() is the
// window origin, and its size() is the size of the content area.
diff --git a/chrome/browser/browser_window_controller.h b/chrome/browser/browser_window_controller.h
index 9dffe322..f79cd4e 100644
--- a/chrome/browser/browser_window_controller.h
+++ b/chrome/browser/browser_window_controller.h
@@ -14,12 +14,14 @@ class Browser;
class BrowserWindow;
@class TabBarView;
@class TabContentsController;
+@class TabStripController;
@interface BrowserWindowController :
NSWindowController<NSUserInterfaceValidations> {
@private
Browser* browser_;
BrowserWindow* windowShim_;
+ TabStripController* tabStripController_;
TabContentsController* contentsController_;
IBOutlet NSBox* contentBox_;
diff --git a/chrome/browser/browser_window_controller.mm b/chrome/browser/browser_window_controller.mm
index 8838a02..33892a3 100644
--- a/chrome/browser/browser_window_controller.mm
+++ b/chrome/browser/browser_window_controller.mm
@@ -6,7 +6,7 @@
#import "chrome/browser/browser_window_cocoa.h"
#import "chrome/browser/browser_window_controller.h"
#import "chrome/browser/cocoa/tab_bar_view.h"
-#import "chrome/browser/cocoa/tab_contents_controller.h"
+#import "chrome/browser/cocoa/tab_strip_controller.h"
@implementation BrowserWindowController
@@ -16,6 +16,7 @@
- (id)initWithBrowser:(Browser*)browser {
if ((self = [super initWithWindowNibName:@"BrowserWindow"])) {
browser_ = browser;
+ DCHECK(browser_);
windowShim_ = new BrowserWindowCocoa(self, [self window]);
}
return self;
@@ -25,6 +26,7 @@
browser_->CloseAllTabs();
delete browser_;
delete windowShim_;
+ [tabStripController_ release];
[contentsController_ release];
[super dealloc];
}
@@ -35,6 +37,14 @@
}
- (void)windowDidLoad {
+ // Create a controller for the tab strip, giving it the model object for
+ // this window's Browser and the tab strip view. The controller will handle
+ // registering for the appropriate tab notifications from the back-end and
+ // managing the creation of new tabs.
+ tabStripController_ =
+ [[TabStripController alloc]
+ initWithView:tabBarView_ model:browser_->tabstrip_model()];
+
// Place the tab bar above the content box and add it to the view hierarchy
// as a sibling of the content view so it can overlap with the window frame.
NSRect tabFrame = [contentBox_ frame];
@@ -42,17 +52,6 @@
tabFrame.size.height = NSHeight([tabBarView_ frame]);
[tabBarView_ setFrame:tabFrame];
[[[[self window] contentView] superview] addSubview:tabBarView_];
-
- // bring in a single copy of the tab contents for now. We'll do this for
- // real when we hook up the "add tab to browser window" logic flow.
- // TODO(pinkerton): hook this up to the tab code
- contentsController_ =
- [[TabContentsController alloc] initWithNibName:@"TabContents" bundle:nil];
- NSView* view = [contentsController_ view];
- NSRect frame = [[[self window] contentView] bounds];
- frame.size.height -= 14.0;
- [view setFrame:frame];
- [[[self window] contentView] addSubview:view];
}
- (void)destroyBrowser {
diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h
new file mode 100644
index 0000000..85cce9f
--- /dev/null
+++ b/chrome/browser/cocoa/tab_strip_controller.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2009 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_TAB_STRIP_CONTROLLER_H_
+#define CHROME_BROWSER_COCOA_TAB_STRIP_CONTROLLER_H_
+
+#import <Cocoa/Cocoa.h>
+
+@class TabBarView;
+class TabStripBridge;
+class TabStripModel;
+
+// 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
+// the other Cocoa-y aspects.
+//
+// When a new tab is created, it loads the contents, including
+// toolbar, from a separate nib file and replaces the contentView of the
+// window. As tabs are switched, the single child of the contentView is
+// swapped around to hold the contents (toolbar and all) representing that tab.
+
+@interface TabStripController : NSObject {
+ @private
+ TabBarView* tabView_; // weak
+ NSButton* newTabButton_;
+ TabStripBridge* bridge_;
+ TabStripModel* model_;
+ // maps TabContents to a TabContentsController (which owns the parent view
+ // for the toolbar and associated tab contents)
+ NSMutableDictionary* tabContentsToController_;
+}
+
+// Initialize the controller with a view and model. Both must be non-nil.
+- (id)initWithView:(TabBarView*)view model:(TabStripModel*)model;
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_TAB_STRIP_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
new file mode 100644
index 0000000..9bd5fc5
--- /dev/null
+++ b/chrome/browser/cocoa/tab_strip_controller.mm
@@ -0,0 +1,283 @@
+// Copyright (c) 2009 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/tab_strip_controller.h"
+
+#import "chrome/app/chrome_dll_resource.h"
+#import "chrome/browser/cocoa/tab_bar_view.h"
+#import "chrome/browser/cocoa/tab_cell.h"
+#import "chrome/browser/cocoa/tab_contents_controller.h"
+#import "chrome/browser/tabs/tab_strip_model.h"
+
+// the private methods the brige object needs from the controller
+@interface TabStripController(BridgeMethods)
+- (void)insertTabWithContents:(TabContents*)contents
+ atIndex:(NSInteger)index
+ inForeground:(bool)inForeground;
+- (void)selectTabWithContents:(TabContents*)newContents
+ previousContents:(TabContents*)oldContents
+ atIndex:(NSInteger)index
+ userGesture:(bool)wasUserGesture;
+@end
+
+// A C++ bridge class to handle receiving notifications from the C++ tab
+// strip model. Doesn't do much on its own, just sends everything straight
+// to the Cocoa controller.
+class TabStripBridge : public TabStripModelObserver {
+ public:
+ TabStripBridge(TabStripModel* model, TabStripController* controller);
+ ~TabStripBridge();
+
+ // Overridden from TabStripModelObserver
+ virtual void TabInsertedAt(TabContents* contents,
+ int index,
+ bool foreground);
+ virtual void TabClosingAt(TabContents* contents, int index);
+ virtual void TabDetachedAt(TabContents* contents, int index);
+ virtual void TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture);
+ virtual void TabMoved(TabContents* contents,
+ int from_index,
+ int to_index);
+ virtual void TabChangedAt(TabContents* contents, int index);
+ virtual void TabStripEmpty();
+
+ private:
+ TabStripController* controller_; // weak, owns me
+ TabStripModel* model_; // weak, owned by Browser
+};
+
+@implementation TabStripController
+
+- (id)initWithView:(TabBarView*)view model:(TabStripModel*)model {
+ DCHECK(view && model);
+ if ((self = [super init])) {
+ tabView_ = view;
+ model_ = model;
+ bridge_ = new TabStripBridge(model, self);
+ tabContentsToController_ = [[NSMutableDictionary alloc] init];
+
+ // Create the new tab button separate from the nib so we can make sure
+ // it's always at the end of the subview list.
+ NSImage* image = [NSImage imageNamed:@"newtab"];
+ NSRect frame = NSMakeRect(0, 0, [image size].width, [image size].height);
+ newTabButton_ = [[NSButton alloc] initWithFrame:frame];
+ [newTabButton_ setImage:image];
+ [newTabButton_ setTarget:nil];
+ [newTabButton_ setAction:@selector(commandDispatch:)];
+ [newTabButton_ setTag:IDC_NEW_TAB];
+ [newTabButton_ setButtonType:NSMomentaryPushInButton];
+ [newTabButton_ setBordered:NO];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ delete bridge_;
+ [tabContentsToController_ release];
+ [newTabButton_ release];
+ [super dealloc];
+}
+
+// Look up the controller associated with |contents| in the map, using its
+// pointer as the key into our dictionary.
+- (TabContentsController*)controllerWithContents:(TabContents*)contents {
+ NSValue* key = [NSValue valueWithPointer:contents];
+ return [tabContentsToController_ objectForKey:key];
+}
+
+// Finds the associated TabContentsController for |contents| using the
+// internal dictionary and swaps out the sole child of the contentArea to
+// display its contents.
+- (void)swapInTabContents:(TabContents*)contents {
+ // Look up the associated controller
+ TabContentsController* controller = [self controllerWithContents:contents];
+
+ // Resize the new view to fit the window
+ NSView* contentView = [[tabView_ window] contentView];
+ NSView* newView = [controller view];
+ NSRect frame = [contentView bounds];
+ frame.size.height -= 14.0;
+ [newView setFrame:frame];
+
+ // Remove the old view from the view hierarchy. We know there's only one
+ // child of the contentView because we're the one who put it there.
+ NSView* oldView = [[contentView subviews] objectAtIndex:0];
+ [contentView replaceSubview:oldView with:newView];
+}
+
+// Create a new tab view and set its cell correctly so it draws the way we
+// want it to.
+- (NSButton*)newTabWithFrame:(NSRect)frame {
+ NSButton* button = [[[NSButton alloc] initWithFrame:frame] autorelease];
+ TabCell* cell = [[[TabCell alloc] init] autorelease];
+ [button setCell:cell];
+ [button setButtonType:NSMomentaryPushInButton];
+ [button setTitle:@"New Tab"];
+ [button setBezelStyle:NSRegularSquareBezelStyle];
+ [button setTarget:self];
+ [button setAction:@selector(selectTab:)];
+
+ return button;
+}
+
+// Returns the number of tab buttons in the tab strip by counting the children.
+// Recall the last view is the "new tab" button, so the number of tabs is one
+// less than the count.
+- (NSInteger)numberOfTabViews {
+ return [[tabView_ subviews] count] - 1;
+}
+
+// Returns the index of the subview |view|. Returns -1 if not present.
+- (NSInteger)indexForTabView:(NSView*)view {
+ NSInteger index = -1;
+ const int numSubviews = [self numberOfTabViews];
+ for (int i = 0; i < numSubviews; i++) {
+ if ([[tabView_ subviews] objectAtIndex:i] == view)
+ index = i;
+ }
+ return index;
+}
+
+// Called when the user clicks a tab. Tell the model the selection has changed,
+// which feeds back into us via a notification.
+- (void)selectTab:(id)sender {
+ int index = [self indexForTabView:sender]; // for testing...
+ if (index >= 0 && model_->ContainsIndex(index))
+ model_->SelectTabContentsAt(index, true);
+}
+
+// Return the frame for a new tab that will go to the immediate right of the
+// tab at |index|. If |index| is 0, this will be the first tab, indented so
+// as to not cover the window controls.
+- (NSRect)frameForNewTabAtIndex:(NSInteger)index {
+ const short kIndentLeavingSpaceForControls = 66;
+ const short kNewTabWidth = 160;
+ const short kTabOverlap = 16;
+
+ short xOffset = kIndentLeavingSpaceForControls;
+ if (index > 0) {
+ NSRect previousTab = [[[tabView_ subviews] objectAtIndex:index - 1] frame];
+ xOffset = NSMaxX(previousTab) - kTabOverlap;
+ }
+
+ return NSMakeRect(xOffset, 0, kNewTabWidth, [tabView_ frame].size.height);
+}
+
+// Called when a notification is received from the model to insert a new tab
+// at |index|.
+- (void)insertTabWithContents:(TabContents*)contents
+ atIndex:(NSInteger)index
+ inForeground:(bool)inForeground {
+ DCHECK(contents);
+ DCHECK(index == TabStripModel::kNoTab || model_->ContainsIndex(index));
+
+ // TODO(pinkerton): handle tab dragging in here
+
+ // Make a new tab. Load the contents of this tab from the nib and associate
+ // the new controller with |contents| so it can be looked up later.
+ // TODO(pinkerton): will eventually need to pass |contents| to the
+ // controller to complete hooking things up.
+ TabContentsController* contentsController =
+ [[[TabContentsController alloc] initWithNibName:@"TabContents" bundle:nil]
+ autorelease];
+ NSValue* key = [NSValue valueWithPointer:contents];
+ [tabContentsToController_ setObject:contentsController forKey:key];
+
+ // Remove the new tab button so the only views present are the tabs,
+ // we'll add it back when we're done
+ [newTabButton_ removeFromSuperview];
+
+ // Make a new tab view and add it to the strip.
+ // TODO(pinkerton): move everyone else over and animate. Also will need to
+ // move the "add tab" button over.
+ NSRect newTabFrame = [self frameForNewTabAtIndex:index];
+ NSButton* newView = [self newTabWithFrame:newTabFrame];
+ [tabView_ addSubview:newView];
+
+ // Add the new tab button back in to the right of the last tab.
+ const NSInteger kNewTabXOffset = 10;
+ NSRect lastTab =
+ [[[tabView_ subviews] objectAtIndex:[[tabView_ subviews] count] - 1] frame];
+ NSInteger maxRightEdge = NSMaxX(lastTab);
+ NSRect newTabButtonFrame = [newTabButton_ frame];
+ newTabButtonFrame.origin.x = maxRightEdge + kNewTabXOffset;
+ [newTabButton_ setFrame:newTabButtonFrame];
+ [tabView_ addSubview:newTabButton_];
+
+ // Select the newly created tab if in the foreground
+ if (inForeground)
+ [self swapInTabContents:contents];
+}
+
+// Called when a notification is received from the model to select a particular
+// tab. Swaps in the toolbar and content area associated with |newContents|.
+- (void)selectTabWithContents:(TabContents*)newContents
+ previousContents:(TabContents*)oldContents
+ atIndex:(NSInteger)index
+ userGesture:(bool)wasUserGesture {
+ // De-select all other tabs and select the new tab.
+ const int numSubviews = [self numberOfTabViews];
+ for (int i = 0; i < numSubviews; i++) {
+ NSButton* current = [[tabView_ subviews] objectAtIndex:i];
+ [current setState:(i == index) ? NSOnState : NSOffState];
+ }
+
+ // Swap in the contents for the new tab
+ [self swapInTabContents:newContents];
+}
+
+@end
+
+//--------------------------------------------------------------------------
+
+TabStripBridge::TabStripBridge(TabStripModel* model,
+ TabStripController* controller)
+ : controller_(controller), model_(model) {
+ // Register to be a listener on the model so we can get updates and tell
+ // the TabStripController about them.
+ model_->AddObserver(this);
+}
+
+TabStripBridge::~TabStripBridge() {
+ // Remove ourselves from receiving notifications.
+ model_->RemoveObserver(this);
+}
+
+void TabStripBridge::TabInsertedAt(TabContents* contents,
+ int index,
+ bool foreground) {
+ [controller_ insertTabWithContents:contents
+ atIndex:index
+ inForeground:foreground];
+}
+
+void TabStripBridge::TabClosingAt(TabContents* contents, int index) {
+}
+
+void TabStripBridge::TabDetachedAt(TabContents* contents, int index) {
+}
+
+void TabStripBridge::TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture) {
+ [controller_ selectTabWithContents:new_contents
+ previousContents:old_contents
+ atIndex:index
+ userGesture:user_gesture];
+}
+
+void TabStripBridge::TabMoved(TabContents* contents,
+ int from_index,
+ int to_index) {
+}
+
+void TabStripBridge::TabChangedAt(TabContents* contents, int index) {
+}
+
+void TabStripBridge::TabStripEmpty() {
+}
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj
index c2cff115..db5f5ea 100644
--- a/chrome/chrome.xcodeproj/project.pbxproj
+++ b/chrome/chrome.xcodeproj/project.pbxproj
@@ -216,7 +216,6 @@
826852120F2FD143009F6555 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82684C5F0F2FAE68009F6555 /* Security.framework */; };
826852130F2FD146009F6555 /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D1F5AB60F2A6EE90040C1E3 /* libpng.a */; };
826852160F2FD156009F6555 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 82684CCF0F2FAEC2009F6555 /* SystemConfiguration.framework */; };
- 826852180F2FD188009F6555 /* tab_contents_controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C50E90F2A11FC00B393B8 /* tab_contents_controller.mm */; };
826852190F2FD190009F6555 /* libsdch.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 82684D0A0F2FB101009F6555 /* libsdch.a */; };
826853320F30ADF5009F6555 /* child_process.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFB890E9D4C9F009A6919 /* child_process.cc */; };
826853350F30AE04009F6555 /* render_thread.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D640CD10EAE868600EBCFC0 /* render_thread.cc */; };
@@ -351,6 +350,9 @@
E45076E50F153AB6003BE099 /* unzip.cc in Sources */ = {isa = PBXBuildFile; fileRef = E45076E40F153AB6003BE099 /* unzip.cc */; };
E450775F0F154036003BE099 /* mru_cache_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBD40E9D4C9F009A6919 /* mru_cache_unittest.cc */; };
E45077620F15405C003BE099 /* notification_service_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFBDB0E9D4C9F009A6919 /* notification_service_unittest.cc */; };
+ E455DCF00F320CF700DD4383 /* tab_strip_controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C55EE0F30EFF500B393B8 /* tab_strip_controller.mm */; };
+ E455DCF10F320CFE00DD4383 /* tab_contents_controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C50E90F2A11FC00B393B8 /* tab_contents_controller.mm */; };
+ E455DDBA0F3227A600DD4383 /* tab_cell.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C50D80F292EAA00B393B8 /* tab_cell.mm */; };
E46C42130F1D3DD200B393B8 /* user_script_master.cc in Sources */ = {isa = PBXBuildFile; fileRef = 0082A7510F16987A000AA0EF /* user_script_master.cc */; };
E46C4A740F1FE04F00B393B8 /* app_controller_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C45990F1F88D100B393B8 /* app_controller_mac.mm */; };
E46C4B3F0F21095400B393B8 /* url_request_intercept_job.cc in Sources */ = {isa = PBXBuildFile; fileRef = 4D7BFCC20E9D4D6B009A6919 /* url_request_intercept_job.cc */; };
@@ -366,8 +368,6 @@
E46C50560F291C1E00B393B8 /* reload.pdf in Resources */ = {isa = PBXBuildFile; fileRef = E46C50540F291C1E00B393B8 /* reload.pdf */; };
E46C50580F291C3B00B393B8 /* newtab.pdf in Resources */ = {isa = PBXBuildFile; fileRef = E46C50570F291C3B00B393B8 /* newtab.pdf */; };
E46C50D90F292EAA00B393B8 /* tab_bar_view.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C50D60F292EAA00B393B8 /* tab_bar_view.mm */; };
- E46C50DA0F292EAA00B393B8 /* tab_cell.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C50D80F292EAA00B393B8 /* tab_cell.mm */; };
- E46C50EA0F2A11FC00B393B8 /* tab_contents_controller.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C50E90F2A11FC00B393B8 /* tab_contents_controller.mm */; };
E46C50EF0F2A12DC00B393B8 /* TabContents.xib in Resources */ = {isa = PBXBuildFile; fileRef = E46C50ED0F2A12DC00B393B8 /* TabContents.xib */; };
E46C51240F2A14A300B393B8 /* go.pdf in Resources */ = {isa = PBXBuildFile; fileRef = E46C51230F2A14A300B393B8 /* go.pdf */; };
E46C51640F2A1DAB00B393B8 /* toolbar_view.mm in Sources */ = {isa = PBXBuildFile; fileRef = E46C51630F2A1DAB00B393B8 /* toolbar_view.mm */; };
@@ -2110,6 +2110,8 @@
E46C53A80F2F662F00B393B8 /* tab_strip_model_order_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tab_strip_model_order_controller.h; path = tabs/tab_strip_model_order_controller.h; sourceTree = "<group>"; };
E46C53A90F2F662F00B393B8 /* tab_strip_model_order_controller.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tab_strip_model_order_controller.cc; path = tabs/tab_strip_model_order_controller.cc; sourceTree = "<group>"; };
E46C53E70F2F69AD00B393B8 /* tab_strip_model_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = tab_strip_model_unittest.cc; path = tabs/tab_strip_model_unittest.cc; sourceTree = "<group>"; };
+ E46C55ED0F30EFF500B393B8 /* tab_strip_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tab_strip_controller.h; path = cocoa/tab_strip_controller.h; sourceTree = "<group>"; };
+ E46C55EE0F30EFF500B393B8 /* tab_strip_controller.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = tab_strip_controller.mm; path = cocoa/tab_strip_controller.mm; sourceTree = "<group>"; };
E48B684C0F2630D3002E47EC /* browser_window_factory.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = browser_window_factory.mm; sourceTree = "<group>"; };
E48B68550F26330C002E47EC /* browser_window_controller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser_window_controller.h; sourceTree = "<group>"; };
E48B68560F26330C002E47EC /* browser_window_controller.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = browser_window_controller.mm; sourceTree = "<group>"; };
@@ -3629,6 +3631,8 @@
E46C50D80F292EAA00B393B8 /* tab_cell.mm */,
E46C50E80F2A11FC00B393B8 /* tab_contents_controller.h */,
E46C50E90F2A11FC00B393B8 /* tab_contents_controller.mm */,
+ E46C55ED0F30EFF500B393B8 /* tab_strip_controller.h */,
+ E46C55EE0F30EFF500B393B8 /* tab_strip_controller.mm */,
E46C51980F2A20CC00B393B8 /* toolbar_button_cell.h */,
E46C51990F2A20CC00B393B8 /* toolbar_button_cell.mm */,
E46C51620F2A1DAB00B393B8 /* toolbar_view.h */,
@@ -4574,6 +4578,9 @@
F775995035B63E51251B0922 /* ssl_error_info.cc in Sources */,
E4F3245D0EE5CFDF002533CE /* starred_url_database.cc in Sources */,
E45075EE0F150ABA003BE099 /* sync_resource_handler.cc in Sources */,
+ E455DDBA0F3227A600DD4383 /* tab_cell.mm in Sources */,
+ E455DCF10F320CFE00DD4383 /* tab_contents_controller.mm in Sources */,
+ E455DCF00F320CF700DD4383 /* tab_strip_controller.mm in Sources */,
E46C53A40F2F660900B393B8 /* tab_strip_model.cc in Sources */,
E46C53AA0F2F662F00B393B8 /* tab_strip_model_order_controller.cc in Sources */,
82684FEB0F2FC650009F6555 /* template_url.cc in Sources */,
@@ -4639,7 +4646,6 @@
E48FB9870EC4EBA10052B72B /* safe_browsing_database_unittest.cc in Sources */,
4D7BFB7F0E9D4C63009A6919 /* safe_browsing_util_unittest.cc in Sources */,
E4F324980EE5D7DE002533CE /* snippet_unittest.cc in Sources */,
- 826852180F2FD188009F6555 /* tab_contents_controller.mm in Sources */,
4D7BFB3E0E9D4C2F009A6919 /* text_database_unittest.cc in Sources */,
4D7BFB610E9D4C4B009A6919 /* units_unittest.cc in Sources */,
B503E0FC0F01764800547DC6 /* user_script_slave_unittest.cc in Sources */,
@@ -4728,8 +4734,6 @@
E45062EB0EE9877F003BE099 /* chrome_dll_main.cc in Sources */,
E45060F20EE87D41003BE099 /* chrome_exe_main.mm in Sources */,
E46C50D90F292EAA00B393B8 /* tab_bar_view.mm in Sources */,
- E46C50DA0F292EAA00B393B8 /* tab_cell.mm in Sources */,
- E46C50EA0F2A11FC00B393B8 /* tab_contents_controller.mm in Sources */,
E46C519A0F2A20CC00B393B8 /* toolbar_button_cell.mm in Sources */,
E46C51640F2A1DAB00B393B8 /* toolbar_view.mm in Sources */,
);
diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc
index 95dc2d4..1f87188 100644
--- a/chrome/common/temp_scaffolding_stubs.cc
+++ b/chrome/common/temp_scaffolding_stubs.cc
@@ -102,12 +102,33 @@ bool BrowserInit::LaunchBrowserImpl(const CommandLine& parsed_command_line,
DCHECK(profile);
// this code is a simplification of BrowserInit::LaunchWithProfile::Launch()
- Browser* browser = Browser::Create(profile);
- browser->window()->Show();
+ std::vector<GURL> urls_to_open;
+ urls_to_open.push_back(GURL("http://dev.chromium.org"));
+ urls_to_open.push_back(GURL("http://crbug.com"));
+ urls_to_open.push_back(GURL("http://icanhavecheezeburger.com"));
+ Browser* browser = NULL;
+ browser = OpenURLsInBrowser(browser, profile, urls_to_open);
return true;
}
+// a simplification of BrowserInit::LaunchWithProfile::OpenURLsInBrowser
+Browser* BrowserInit::OpenURLsInBrowser(
+ Browser* browser,
+ Profile* profile,
+ const std::vector<GURL>& urls) {
+ DCHECK(!urls.empty());
+ if (!browser || browser->type() != Browser::TYPE_NORMAL)
+ browser = Browser::Create(profile);
+
+ for (size_t i = 0; i < urls.size(); ++i) {
+ browser->AddTabWithURL(
+ urls[i], GURL(), PageTransition::START_PAGE, (i == 0), NULL);
+ }
+ browser->window()->Show();
+ return browser;
+}
+
//--------------------------------------------------------------------------
UserDataManager* UserDataManager::instance_ = NULL;
@@ -188,12 +209,6 @@ GURL Browser::GetHomePage() {
return GURL("http://dev.chromium.org");
}
-TabContents* Browser::AddTabWithURL(
- const GURL& url, const GURL& referrer, PageTransition::Type transition,
- bool foreground, SiteInstance* instance) {
- return new TabContents;
-}
-
void Browser::LoadingStateChanged(TabContents* source) {
}
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index 03f3c146..79ea9c5 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -81,6 +81,9 @@ class BrowserInit {
static bool LaunchBrowserImpl(const CommandLine& parsed_command_line,
Profile* profile, const std::wstring& cur_dir,
bool process_startup, int* return_code);
+ static Browser* OpenURLsInBrowser(Browser* browser,
+ Profile* profile,
+ const std::vector<GURL>& urls);
};
class FirstRun {
@@ -324,6 +327,8 @@ class TabContents {
bool is_loading() const { return false; }
void CloseContents() { };
void SetupController(Profile* profile) { }
+ bool WasHidden() { return false; }
+ void RestoreFocus() { }
static TabContentsType TypeForURL(GURL* url) { return TAB_CONTENTS_WEB; }
static TabContents* CreateWithType(TabContentsType type,
Profile* profile,