diff options
author | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-12 16:35:23 +0000 |
---|---|---|
committer | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-12 16:35:23 +0000 |
commit | 30beb604b883f9219aa33c426871023fe4b52209 (patch) | |
tree | 84b5bede0a19e9f4db035f4a2663a6269acd32bc | |
parent | 8485f17afe566edb0cbe46ec30d5bc0c117619a4 (diff) | |
download | chromium_src-30beb604b883f9219aa33c426871023fe4b52209.zip chromium_src-30beb604b883f9219aa33c426871023fe4b52209.tar.gz chromium_src-30beb604b883f9219aa33c426871023fe4b52209.tar.bz2 |
Add a TabController class to manage a TabView (with corresponding xib). Rewrite strip controller to create and manage TabControllers instead of NSButtons.
Review URL: http://codereview.chromium.org/43137
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11541 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/nibs/en.lproj/TabView.xib | 426 | ||||
-rw-r--r-- | chrome/app/theme/nav.pdf | bin | 0 -> 2324 bytes | |||
-rw-r--r-- | chrome/browser/cocoa/tab_controller.h | 44 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_controller.mm | 53 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.h | 14 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.mm | 79 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_view.h | 23 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_view.mm | 50 | ||||
-rw-r--r-- | chrome/chrome.gyp | 9 |
9 files changed, 653 insertions, 45 deletions
diff --git a/chrome/app/nibs/en.lproj/TabView.xib b/chrome/app/nibs/en.lproj/TabView.xib new file mode 100644 index 0000000..48fd1c8 --- /dev/null +++ b/chrome/app/nibs/en.lproj/TabView.xib @@ -0,0 +1,426 @@ +<?xml version="1.0" encoding="UTF-8"?> +<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="7.03"> + <data> + <int key="IBDocument.SystemTarget">1050</int> + <string key="IBDocument.SystemVersion">9F33</string> + <string key="IBDocument.InterfaceBuilderVersion">677</string> + <string key="IBDocument.AppKitVersion">949.34</string> + <string key="IBDocument.HIToolboxVersion">352.00</string> + <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> + <bool key="EncodedWithXMLCoder">YES</bool> + <integer value="17"/> + </object> + <object class="NSArray" key="IBDocument.PluginDependencies"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>com.apple.InterfaceBuilderKit</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + </object> + <object class="NSMutableDictionary" key="IBDocument.Metadata"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + </object> + <object class="NSMutableArray" key="IBDocument.RootObjects" id="1000"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSCustomObject" id="1001"> + <string key="NSClassName">TabController</string> + </object> + <object class="NSCustomObject" id="1003"> + <string key="NSClassName">FirstResponder</string> + </object> + <object class="NSCustomObject" id="1004"> + <string key="NSClassName">NSApplication</string> + </object> + <object class="NSCustomView" id="1005"> + <reference key="NSNextResponder"/> + <int key="NSvFlags">268</int> + <object class="NSMutableArray" key="NSSubviews"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSButton" id="279592484"> + <reference key="NSNextResponder" ref="1005"/> + <int key="NSvFlags">274</int> + <string key="NSFrameSize">{160, 25}</string> + <reference key="NSSuperview" ref="1005"/> + <bool key="NSEnabled">YES</bool> + <object class="NSButtonCell" key="NSCell" id="707804163"> + <int key="NSCellFlags">67239424</int> + <int key="NSCellFlags2">0</int> + <string key="NSContents">Label</string> + <object class="NSFont" key="NSSupport"> + <string key="NSName">LucidaGrande</string> + <double key="NSSize">1.100000e+01</double> + <int key="NSfFlags">16</int> + </object> + <reference key="NSControlView" ref="279592484"/> + <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="NSImageView" id="569334633"> + <reference key="NSNextResponder" ref="1005"/> + <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">{{5, 46}, {32, 32}}</string> + <reference key="NSSuperview" ref="1005"/> + <bool key="NSEnabled">YES</bool> + <object class="NSImageCell" key="NSCell" id="601843736"> + <int key="NSCellFlags">130560</int> + <int key="NSCellFlags2">33554432</int> + <object class="NSCustomResource" key="NSContents"> + <string key="NSClassName">NSImage</string> + <string key="NSResourceName">NSUser</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 class="NSProgressIndicator" id="58797509"> + <reference key="NSNextResponder" ref="1005"/> + <int key="NSvFlags">1321</int> + <object class="NSPSMatrix" key="NSDrawMatrix"/> + <string key="NSFrame">{{131, 4}, {16, 16}}</string> + <reference key="NSSuperview" ref="1005"/> + <int key="NSpiFlags">28938</int> + <double key="NSMinValue">1.600000e+01</double> + <double key="NSMaxValue">1.000000e+02</double> + </object> + </object> + <string key="NSFrameSize">{160, 25}</string> + <reference key="NSSuperview"/> + <string key="NSClassName">TabView</string> + </object> + </object> + <object class="IBObjectContainer" key="IBDocument.Objects"> + <object class="NSMutableArray" key="connectionRecords"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">backgroundButton_</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="279592484"/> + </object> + <int key="connectionID">25</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">progressIndicator_</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="58797509"/> + </object> + <int key="connectionID">27</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBBindingConnection" key="connection"> + <string key="label">title: title</string> + <reference key="source" ref="707804163"/> + <reference key="destination" ref="1001"/> + <object class="NSNibBindingConnector" key="connector"> + <reference key="NSSource" ref="707804163"/> + <reference key="NSDestination" ref="1001"/> + <string key="NSLabel">title: title</string> + <string key="NSBinding">title</string> + <string key="NSKeyPath">title</string> + <int key="NSNibBindingConnectorVersion">2</int> + </object> + </object> + <int key="connectionID">29</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBBindingConnection" key="connection"> + <string key="label">animate: loading</string> + <reference key="source" ref="58797509"/> + <reference key="destination" ref="1001"/> + <object class="NSNibBindingConnector" key="connector"> + <reference key="NSSource" ref="58797509"/> + <reference key="NSDestination" ref="1001"/> + <string key="NSLabel">animate: loading</string> + <string key="NSBinding">animate</string> + <string key="NSKeyPath">loading</string> + <int key="NSNibBindingConnectorVersion">2</int> + </object> + </object> + <int key="connectionID">31</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBBindingConnection" key="connection"> + <string key="label">hidden: loading</string> + <reference key="source" ref="58797509"/> + <reference key="destination" ref="1001"/> + <object class="NSNibBindingConnector" key="connector"> + <reference key="NSSource" ref="58797509"/> + <reference key="NSDestination" ref="1001"/> + <string key="NSLabel">hidden: loading</string> + <string key="NSBinding">hidden</string> + <string key="NSKeyPath">loading</string> + <object class="NSDictionary" key="NSOptions"> + <string key="NS.key.0">NSValueTransformerName</string> + <string key="NS.object.0">NSNegateBoolean</string> + </object> + <int key="NSNibBindingConnectorVersion">2</int> + </object> + </object> + <int key="connectionID">43</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBBindingConnection" key="connection"> + <string key="label">image: image</string> + <reference key="source" ref="279592484"/> + <reference key="destination" ref="1001"/> + <object class="NSNibBindingConnector" key="connector" id="703997475"> + <reference key="NSSource" ref="279592484"/> + <reference key="NSDestination" ref="1001"/> + <string key="NSLabel">image: image</string> + <string key="NSBinding">image</string> + <string key="NSKeyPath">image</string> + <int key="NSNibBindingConnectorVersion">2</int> + </object> + </object> + <int key="connectionID">44</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBBindingConnection" key="connection"> + <string key="label">title: title</string> + <reference key="source" ref="279592484"/> + <reference key="destination" ref="1001"/> + <object class="NSNibBindingConnector" key="connector"> + <reference key="NSSource" ref="279592484"/> + <reference key="NSDestination" ref="1001"/> + <string key="NSLabel">title: title</string> + <string key="NSBinding">title</string> + <string key="NSKeyPath">title</string> + <reference key="NSPreviousConnector" ref="703997475"/> + <int key="NSNibBindingConnectorVersion">2</int> + </object> + </object> + <int key="connectionID">45</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">view</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="1005"/> + </object> + <int key="connectionID">46</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">controller_</string> + <reference key="source" ref="1005"/> + <reference key="destination" ref="1001"/> + </object> + <int key="connectionID">47</int> + </object> + </object> + <object class="IBMutableOrderedSet" key="objectRecords"> + <object class="NSArray" key="orderedObjects"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="IBObjectRecord"> + <int key="objectID">0</int> + <object class="NSArray" key="object" id="1002"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + <reference key="children" ref="1000"/> + <nil key="parent"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-2</int> + <reference key="object" ref="1001"/> + <reference key="parent" ref="1002"/> + <string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-1</int> + <reference key="object" ref="1003"/> + <reference key="parent" ref="1002"/> + <string key="objectName">First Responder</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">-3</int> + <reference key="object" ref="1004"/> + <reference key="parent" ref="1002"/> + <string key="objectName">Application</string> + </object> + <object class="IBObjectRecord"> + <int key="objectID">1</int> + <reference key="object" ref="1005"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="569334633"/> + <reference ref="58797509"/> + <reference ref="279592484"/> + </object> + <reference key="parent" ref="1002"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">8</int> + <reference key="object" ref="569334633"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="601843736"/> + </object> + <reference key="parent" ref="1005"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">9</int> + <reference key="object" ref="601843736"/> + <reference key="parent" ref="569334633"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">12</int> + <reference key="object" ref="58797509"/> + <reference key="parent" ref="1005"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">17</int> + <reference key="object" ref="279592484"/> + <object class="NSMutableArray" key="children"> + <bool key="EncodedWithXMLCoder">YES</bool> + <reference ref="707804163"/> + </object> + <reference key="parent" ref="1005"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">18</int> + <reference key="object" ref="707804163"/> + <reference key="parent" ref="279592484"/> + </object> + </object> + </object> + <object class="NSMutableDictionary" key="flattenedProperties"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>-1.IBPluginDependency</string> + <string>-2.IBPluginDependency</string> + <string>-3.IBPluginDependency</string> + <string>1.IBEditorWindowLastContentRect</string> + <string>1.IBPluginDependency</string> + <string>1.IBViewEditorWindowController.showingLayoutRectangles</string> + <string>1.WindowOrigin</string> + <string>1.editorWindowContentRectSynchronizationRect</string> + <string>12.IBPluginDependency</string> + <string>17.IBEditorWindowLastContentRect</string> + <string>17.IBPluginDependency</string> + <string>18.CustomClassName</string> + <string>18.IBPluginDependency</string> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilderKit</string> + <string>com.apple.InterfaceBuilderKit</string> + <string>{{833, 498}, {160, 25}}</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <boolean value="NO"/> + <string>{628, 654}</string> + <string>{{217, 442}, {480, 272}}</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>{{77, 725}, {134, 29}}</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>TabCell</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + </object> + </object> + <object class="NSMutableDictionary" key="unlocalizedProperties"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + </object> + <nil key="activeLocalization"/> + <object class="NSMutableDictionary" key="localizations"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + </object> + </object> + <nil key="sourceID"/> + <int key="maxID">49</int> + </object> + <object class="IBClassDescriber" key="IBDocument.Classes"> + <object class="NSMutableArray" key="referencedPartialClassDescriptions"> + <bool key="EncodedWithXMLCoder">YES</bool> + <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 class="IBPartialClassDescription"> + <string key="className">TabController</string> + <string key="superclassName">NSViewController</string> + <object class="NSMutableDictionary" key="outlets"> + <bool key="EncodedWithXMLCoder">YES</bool> + <object class="NSMutableArray" key="dict.sortedKeys"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>backgroundButton_</string> + <string>closeButton_</string> + <string>progressIndicator_</string> + <string>target_</string> + </object> + <object class="NSMutableArray" key="dict.values"> + <bool key="EncodedWithXMLCoder">YES</bool> + <string>NSButton</string> + <string>NSButton</string> + <string>NSProgressIndicator</string> + <string>id</string> + </object> + </object> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">browser/cocoa/tab_controller.h</string> + </object> + </object> + <object class="IBPartialClassDescription"> + <string key="className">TabView</string> + <string key="superclassName">NSView</string> + <object class="NSMutableDictionary" key="outlets"> + <string key="NS.key.0">controller_</string> + <string key="NS.object.0">TabController</string> + </object> + <object class="IBClassDescriptionSource" key="sourceIdentifier"> + <string key="majorKey">IBProjectSource</string> + <string key="minorKey">browser/cocoa/tab_view.h</string> + </object> + </object> + </object> + </object> + <int key="IBDocument.localizationMode">0</int> + <string key="IBDocument.LastKnownRelativeProjectPath">../../../chrome.xcodeproj</string> + <int key="IBDocument.defaultPropertyAccessControl">3</int> + </data> +</archive> diff --git a/chrome/app/theme/nav.pdf b/chrome/app/theme/nav.pdf Binary files differnew file mode 100644 index 0000000..e165627 --- /dev/null +++ b/chrome/app/theme/nav.pdf diff --git a/chrome/browser/cocoa/tab_controller.h b/chrome/browser/cocoa/tab_controller.h new file mode 100644 index 0000000..0760ccd --- /dev/null +++ b/chrome/browser/cocoa/tab_controller.h @@ -0,0 +1,44 @@ +// 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_CONTROLLER_H_ +#define CHROME_BROWSER_COCOA_TAB_CONTROLLER_H_ + +#import <Cocoa/Cocoa.h> + +@class TabView; + +// A class that manages a single tab in the tab strip. Set its target/action +// to be sent a message when the tab is selected by the user clicking. Setting +// the |loading| property to YES visually indicates that this tab is currently +// loading content via a spinner. + +@interface TabController : NSViewController { + @private + IBOutlet NSButton *backgroundButton_; + IBOutlet NSButton *closeButton_; + IBOutlet NSProgressIndicator *progressIndicator_; + BOOL selected_; + BOOL loading_; + NSImage *image_; + id target_; // weak, where actions are sent, eg selectTab: + SEL action_; // selector sent when tab is seleted by clicking +} + +@property(retain, nonatomic) NSImage *image; +@property(assign, nonatomic) BOOL selected; +@property(assign, nonatomic) BOOL loading; +@property(assign, nonatomic) id target; +@property(assign, nonatomic) SEL action; + +// Minimum and maximum allowable tab width. ++ (float)minTabWidth; ++ (float)maxTabWidth; + +// The view associated with this controller, pre-casted as a TabView +- (TabView *)tabView; + +@end + +#endif // CHROME_BROWSER_COCOA_TAB_CONTROLLER_H_ diff --git a/chrome/browser/cocoa/tab_controller.mm b/chrome/browser/cocoa/tab_controller.mm new file mode 100644 index 0000000..1c10172 --- /dev/null +++ b/chrome/browser/cocoa/tab_controller.mm @@ -0,0 +1,53 @@ +// 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_controller.h" + +@implementation TabController + +@synthesize image = image_; +@synthesize loading = loading_; +@synthesize target = target_; +@synthesize action = action_; + ++ (float)minTabWidth { return 64.0; } ++ (float)maxTabWidth { return 160.0; } + +- (TabView*)tabView { + return static_cast<TabView*>([self view]); +} + +- (id)init { + self = [super initWithNibName:@"TabView" bundle:nil]; + if (self != nil) { + [self setImage:[NSImage imageNamed:@"nav"]]; + } + return self; +} + +// Called when the tab's nib is done loading and all outlets are hooked up. +- (void)awakeFromNib { + [[self view] addSubview:backgroundButton_ + positioned:NSWindowBelow + relativeTo:nil]; + // TODO(alcor): figure out what to do with the close button v. cell. Note + // there is no close button in the nib at the moment. + [closeButton_ setWantsLayer:YES]; + [closeButton_ setAlphaValue:0.2]; + [self setSelected:NO]; +} + +- (void)setSelected:(BOOL)selected { + if (selected_ != selected) { + selected_ = selected; + [backgroundButton_ setState:selected]; + [[self view] setNeedsDisplay:YES]; + } +} + +- (BOOL)selected { + return selected_; +} + +@end diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h index bc1f8c0..1e76e40 100644 --- a/chrome/browser/cocoa/tab_strip_controller.h +++ b/chrome/browser/cocoa/tab_strip_controller.h @@ -20,10 +20,11 @@ class ToolbarModel; // 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. +// When a new tab is created, we create a TabController which manages loading +// the contents, including toolbar, from a separate nib file. This controller +// then handles replacing 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 @@ -38,7 +39,10 @@ class ToolbarModel; // for the toolbar and associated tab contents) given an index. This needs // to be kept in the same order as the tab strip's model as we will be // using its index from the TabStripModelObserver calls. - NSMutableArray* tabControllerArray_; + NSMutableArray* tabContentsArray_; + // an array of TabControllers which manage the actual tab views. As above, + // this is kept in the same order as the tab strip model. + NSMutableArray* tabArray_; } // Initialize the controller with a view, model, and command updater for diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm index 2e23032..49cbb56 100644 --- a/chrome/browser/cocoa/tab_strip_controller.mm +++ b/chrome/browser/cocoa/tab_strip_controller.mm @@ -9,6 +9,8 @@ #import "chrome/browser/cocoa/tab_strip_view.h" #import "chrome/browser/cocoa/tab_cell.h" #import "chrome/browser/cocoa/tab_contents_controller.h" +#import "chrome/browser/cocoa/tab_controller.h" +#import "chrome/browser/cocoa/tab_view.h" #import "chrome/browser/tab_contents/tab_contents.h" #import "chrome/browser/tabs/tab_strip_model.h" @@ -71,7 +73,8 @@ class TabStripBridge : public TabStripModelObserver { toolbarModel_ = toolbarModel; commands_ = commands; bridge_ = new TabStripBridge(tabModel, self); - tabControllerArray_ = [[NSMutableArray alloc] init]; + tabContentsArray_ = [[NSMutableArray alloc] init]; + tabArray_ = [[NSMutableArray 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. @@ -91,7 +94,8 @@ class TabStripBridge : public TabStripModelObserver { - (void)dealloc { delete bridge_; - [tabControllerArray_ release]; + [tabContentsArray_ release]; + [tabArray_ release]; [newTabButton_ release]; [super dealloc]; } @@ -99,7 +103,7 @@ class TabStripBridge : public TabStripModelObserver { // Finds the associated TabContentsController at the given |index| and swaps // out the sole child of the contentArea to display its contents. - (void)swapInTabAtIndex:(NSInteger)index { - TabContentsController* controller = [tabControllerArray_ objectAtIndex:index]; + TabContentsController* controller = [tabContentsArray_ objectAtIndex:index]; // Resize the new view to fit the window NSView* contentView = [[tabView_ window] contentView]; @@ -123,24 +127,21 @@ class TabStripBridge : public TabStripModelObserver { // 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; +- (TabController*)newTabWithFrame:(NSRect)frame { + TabController* controller = [[[TabController alloc] init] autorelease]; + [controller setTarget:self]; + [controller setAction:@selector(selectTab:)]; + TabView* view = [controller tabView]; + [view setFrame:frame]; + + return controller; } -// 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. +// Returns the number of tabs in the tab strip. This is just the number +// of TabControllers we know about as there's a 1-to-1 mapping from these +// controllers to a tab. - (NSInteger)numberOfTabViews { - return [[tabView_ subviews] count] - 1; + return [tabArray_ count]; } // Returns the index of the subview |view|. Returns -1 if not present. @@ -167,7 +168,7 @@ class TabStripBridge : public TabStripModelObserver { // as to not cover the window controls. - (NSRect)frameForNewTabAtIndex:(NSInteger)index { const short kIndentLeavingSpaceForControls = 66; - const short kNewTabWidth = 160; + const short kNewTabWidth = [TabController maxTabWidth]; short xOffset = kIndentLeavingSpaceForControls; if (index > 0) { @@ -180,7 +181,7 @@ class TabStripBridge : public TabStripModelObserver { // Handles setting the title of the tab based on the given |contents|. Uses // a canned string if |contents| is NULL. -- (void)setTabTitle:(NSButton*)tab withContents:(TabContents*)contents { +- (void)setTabTitle:(NSViewController*)tab withContents:(TabContents*)contents { NSString* titleString = nil; if (contents) titleString = base::SysUTF16ToNSString(contents->GetTitle()); @@ -208,20 +209,22 @@ class TabStripBridge : public TabStripModelObserver { commands:commands_ toolbarModel:toolbarModel_] autorelease]; - [tabControllerArray_ insertObject:contentsController atIndex:index]; + [tabContentsArray_ insertObject:contentsController atIndex:index]; // 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. + // Make a new tab and add it to the strip. Keep track of its controller. // 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]; + TabController* newController = [self newTabWithFrame:newTabFrame]; + [tabArray_ insertObject:newController atIndex:index]; + NSView* newView = [newController view]; [tabView_ addSubview:newView]; - [self setTabTitle:newView withContents:contents]; + [self setTabTitle:newController withContents:contents]; // Add the new tab button back in to the right of the last tab. const NSInteger kNewTabXOffset = 10; @@ -247,14 +250,14 @@ class TabStripBridge : public TabStripModelObserver { // 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]; + TabController* current = [tabArray_ objectAtIndex:i]; + [current setSelected:(i == index) ? YES : NO]; } // Tell the new tab contents it is about to become the selected tab. Here it // can do things like make sure the toolbar is up to date. TabContentsController* newController = - [tabControllerArray_ objectAtIndex:index]; + [tabContentsArray_ objectAtIndex:index]; [newController willBecomeSelectedTab]; // Swap in the contents for the new tab @@ -270,7 +273,7 @@ class TabStripBridge : public TabStripModelObserver { // will remove all the tab content Cocoa views from the hierarchy. A // subsequent "select tab" notification will follow from the model. To // tell us what to swap in in its absence. - [tabControllerArray_ removeObjectAtIndex:index]; + [tabContentsArray_ removeObjectAtIndex:index]; // Remove the |index|th view from the tab strip NSView* tab = [[tabView_ subviews] objectAtIndex:index]; @@ -286,23 +289,25 @@ class TabStripBridge : public TabStripModelObserver { newFrame.origin.x -= tabWidth - kTabOverlap; [curr setFrame:newFrame]; } + + // Once we're totally done with the tab, delete its controller + [tabArray_ removeObjectAtIndex:index]; } // Called when a notification is received from the model that the given tab // has been updated. - (void)tabChangedWithContents:(TabContents*)contents atIndex:(NSInteger)index { - NSButton* tab = [[tabView_ subviews] objectAtIndex:index]; - [self setTabTitle:tab withContents:contents]; + [self setTabTitle:[tabArray_ objectAtIndex:index] withContents:contents]; TabContentsController* updatedController = - [tabControllerArray_ objectAtIndex:index]; + [tabContentsArray_ objectAtIndex:index]; [updatedController tabDidChange:contents]; } - (LocationBar*)locationBar { TabContentsController* selectedController = - [tabControllerArray_ objectAtIndex:tabModel_->selected_index()]; + [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; return [selectedController locationBar]; } @@ -316,13 +321,13 @@ class TabStripBridge : public TabStripModelObserver { // YES means we're going back to this tab and should put back any state // associated with it. TabContentsController* controller = - [tabControllerArray_ objectAtIndex:tabModel_->GetIndexOfTabContents(tab)]; + [tabContentsArray_ objectAtIndex:tabModel_->GetIndexOfTabContents(tab)]; [controller updateToolbarWithContents:shouldRestore ? tab : nil]; } - (void)setStarredState:(BOOL)isStarred { TabContentsController* selectedController = - [tabControllerArray_ objectAtIndex:tabModel_->selected_index()]; + [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; [selectedController setStarredState:isStarred]; } @@ -337,7 +342,7 @@ class TabStripBridge : public TabStripModelObserver { selectedIndex = 0; } TabContentsController* selectedController = - [tabControllerArray_ objectAtIndex:selectedIndex]; + [tabContentsArray_ objectAtIndex:selectedIndex]; if (!selectedController) return NSZeroRect; return [selectedController growBoxRect]; @@ -349,14 +354,14 @@ class TabStripBridge : public TabStripModelObserver { // a spinner? TabContentsController* selectedController = - [tabControllerArray_ objectAtIndex:tabModel_->selected_index()]; + [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; [selectedController setIsLoading:isLoading]; } // Make the location bar the first responder, if possible. - (void)focusLocationBar { TabContentsController* selectedController = - [tabControllerArray_ objectAtIndex:tabModel_->selected_index()]; + [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; [selectedController focusLocationBar]; } diff --git a/chrome/browser/cocoa/tab_view.h b/chrome/browser/cocoa/tab_view.h new file mode 100644 index 0000000..a1ddee7 --- /dev/null +++ b/chrome/browser/cocoa/tab_view.h @@ -0,0 +1,23 @@ +// 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_VIEW_H_ +#define CHROME_BROWSER_COCOA_TAB_VIEW_H_ + +#import <Cocoa/Cocoa.h> + +@class TabController; + +// A view that handles the event tracking (clicking and dragging) for a tab +// on the tab strip. Relies on an associated TabController to provide a +// target/action for selecting the tab. + +@interface TabView : NSView { + @private + IBOutlet TabController* controller_; +} + +@end + +#endif // CHROME_BROWSER_COCOA_TAB_VIEW_H_ diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm new file mode 100644 index 0000000..ffca1de --- /dev/null +++ b/chrome/browser/cocoa/tab_view.mm @@ -0,0 +1,50 @@ +// 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. + +#include "chrome/browser/cocoa/tab_view.h" + +@implementation TabView + +- (id)initWithFrame:(NSRect)frame { + self = [super initWithFrame:frame]; + if (self) { + // TODO(alcor): register for theming, either here or the cell + // [self gtm_registerForThemeNotifications]; + } + return self; +} + +- (void)dealloc { + // [self gtm_unregisterForThemeNotifications]; + [super dealloc]; +} + +// Overridden so that mouse clicks come to this view (the parent of the +// hierarchy) first. We want to handle clicks and drags in this class and +// leave the background button for display purposes only. +- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { + return YES; +} + +// Determines which view a click in our frame actually hit. It's always this +// view, never a child. +// TODO(alcor): Figure out what to do with the close button. Are we using a +// NSButton for it, or drawing it ourselves with a cell? +- (NSView *)hitTest:(NSPoint)aPoint { + if (NSPointInRect(aPoint, [self frame])) return self; + return nil; +} + +// Handle clicks and drags in this button. We get here because we have +// overridden acceptsFirstMouse: and the click is within our bounds. +- (void)mouseDown:(NSEvent *)theEvent { + // fire the action to select the tab + if ([[controller_ target] respondsToSelector:[controller_ action]]) + [[controller_ target] performSelector:[controller_ action] + withObject:self]; + + // TODO(alcor): handle dragging... +} + +@end diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 2d07d7a..83772a1 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -494,12 +494,14 @@ 'browser/cocoa/tab_cell.mm', 'browser/cocoa/tab_contents_controller.h', 'browser/cocoa/tab_contents_controller.mm', - # 'browser/cocoa/tab_controller.h', - # 'browser/cocoa/tab_controller.mm', + 'browser/cocoa/tab_controller.h', + 'browser/cocoa/tab_controller.mm', 'browser/cocoa/tab_strip_controller.h', 'browser/cocoa/tab_strip_controller.mm', 'browser/cocoa/tab_strip_view.h', 'browser/cocoa/tab_strip_view.mm', + 'browser/cocoa/tab_view.h', + 'browser/cocoa/tab_view.mm', 'browser/cocoa/toolbar_button_cell.h', 'browser/cocoa/toolbar_button_cell.mm', 'browser/cocoa/toolbar_view.h', @@ -1434,11 +1436,12 @@ 'app/nibs/en.lproj/BrowserWindow.xib', 'app/nibs/en.lproj/MainMenu.xib', 'app/nibs/en.lproj/TabContents.xib', - # 'app/nibs/en.lproj/TabView.xib', + 'app/nibs/en.lproj/TabView.xib', 'app/theme/back.pdf', 'app/theme/forward.pdf', 'app/theme/go.pdf', 'app/theme/grow_box.png', + 'app/theme/nav.pdf', 'app/theme/newtab.pdf', 'app/theme/reload.pdf', 'app/theme/sadtab.png', |