diff options
-rw-r--r-- | chrome/app/nibs/English.lproj/BrowserWindow.xib | 161 | ||||
-rw-r--r-- | chrome/app/nibs/English.lproj/MainMenu.xib | 12 | ||||
-rw-r--r-- | chrome/browser/browser.cc | 14 | ||||
-rw-r--r-- | chrome/browser/browser.h | 4 | ||||
-rw-r--r-- | chrome/browser/browser_window_controller.h | 2 | ||||
-rw-r--r-- | chrome/browser/browser_window_controller.mm | 23 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.h | 40 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.mm | 283 | ||||
-rw-r--r-- | chrome/chrome.xcodeproj/project.pbxproj | 16 | ||||
-rw-r--r-- | chrome/common/temp_scaffolding_stubs.cc | 31 | ||||
-rw-r--r-- | chrome/common/temp_scaffolding_stubs.h | 5 |
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, |