diff options
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.h | 3 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 54 | ||||
-rw-r--r-- | chrome/browser/cocoa/command_observer_bridge.h | 41 | ||||
-rw-r--r-- | chrome/browser/cocoa/command_observer_bridge.mm | 26 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_contents_controller.h | 36 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_contents_controller.mm | 147 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.h | 27 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.mm | 63 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_window_controller.h | 18 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_window_controller.mm | 26 | ||||
-rw-r--r-- | chrome/browser/cocoa/toolbar_controller.h | 60 | ||||
-rw-r--r-- | chrome/browser/cocoa/toolbar_controller.mm | 123 |
12 files changed, 347 insertions, 277 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h index f89d979..04deaf58 100644 --- a/chrome/browser/cocoa/browser_window_controller.h +++ b/chrome/browser/cocoa/browser_window_controller.h @@ -11,6 +11,7 @@ #import <Cocoa/Cocoa.h> #import "chrome/browser/cocoa/tab_window_controller.h" +#import "chrome/browser/cocoa/toolbar_view.h" class Browser; class BrowserWindow; @@ -21,11 +22,13 @@ class TabContents; @class TabStripController; class TabStripModelObserverBridge; @class TabStripView; +@class ToolbarController; @interface BrowserWindowController : TabWindowController<NSUserInterfaceValidations> { @private TabStripController* tabStripController_; + ToolbarController* toolbarController_; Browser* browser_; TabStripModelObserverBridge* tabObserver_; BrowserWindowCocoa* windowShim_; diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index 024b5f5..ac78712 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -14,7 +14,11 @@ #import "chrome/browser/cocoa/tab_strip_view.h" #import "chrome/browser/cocoa/tab_strip_controller.h" #import "chrome/browser/cocoa/tab_view.h" +#import "chrome/browser/cocoa/toolbar_controller.h" +@interface BrowserWindowController(Private) +- (void)positionToolbar; +@end @implementation BrowserWindowController @@ -43,7 +47,17 @@ // registering for the appropriate tab notifications from the back-end and // managing the creation of new tabs. tabStripController_ = [[TabStripController alloc] - initWithView:[self tabStripView] browser:browser_]; + initWithView:[self tabStripView] + switchView:[self tabContentArea] + browser:browser_]; + + // Create a controller for the toolbar, giving it the toolbar model object + // and the toolbar view from the nib. The controller will handle + // registering for the appropriate command state changes from the back-end. + toolbarController_ = [[ToolbarController alloc] + initWithModel:browser->toolbar_model() + commands:browser->command_updater()]; + [self positionToolbar]; } return self; } @@ -51,6 +65,7 @@ - (void)dealloc { browser_->CloseAllTabs(); [tabStripController_ release]; + [toolbarController_ release]; delete windowShim_; delete tabObserver_; delete browser_; @@ -62,6 +77,28 @@ return windowShim_; } +// Position |toolbarView_| below the tab strip, but not as a sibling. The +// toolbar is part of the window's contentView, mainly because we want the +// opacity during drags to be the same as the web content. +- (void)positionToolbar { + NSView* contentView = [self tabContentArea]; + NSRect contentFrame = [contentView frame]; + NSView* toolbarView = [toolbarController_ view]; + NSRect toolbarFrame = [toolbarView frame]; + + // Shrink the content area by the height of the toolbar. + contentFrame.size.height -= toolbarFrame.size.height; + [contentView setFrame:contentFrame]; + + // Move the toolbar above the content area, within the window's content view + // (as opposed to the tab strip, which is a sibling). + toolbarFrame.origin.y = NSMaxY(contentFrame); + toolbarFrame.origin.x = 0; + toolbarFrame.size.width = contentFrame.size.width; + [toolbarView setFrame:toolbarFrame]; + [[[self window] contentView] addSubview:toolbarView]; +} + - (void)destroyBrowser { // We need the window to go away now. [self autorelease]; @@ -172,29 +209,27 @@ } - (LocationBar*)locationBar { - return [tabStripController_ locationBar]; + return [toolbarController_ locationBar]; } - (void)updateToolbarWithContents:(TabContents*)tab shouldRestoreState:(BOOL)shouldRestore { - [tabStripController_ updateToolbarWithContents:tab - shouldRestoreState:shouldRestore]; + [toolbarController_ updateToolbarWithContents:shouldRestore ? tab : NULL]; } - (void)setStarredState:(BOOL)isStarred { - [tabStripController_ setStarredState:isStarred]; + [toolbarController_ setStarredState:isStarred]; } // Return the rect, in WebKit coordinates (flipped), of the window's grow box // in the coordinate system of the content area of the currently selected tab. // |windowGrowBox| needs to be in the window's coordinate system. - (NSRect)selectedTabGrowBoxRect { - return [tabStripController_ - selectedTabGrowBoxRect]; + return [tabStripController_ selectedTabGrowBoxRect]; } - (void)setIsLoading:(BOOL)isLoading { - [tabStripController_ setIsLoading:isLoading]; + [toolbarController_ setIsLoading:isLoading]; } // Called to start/stop the loading animations. @@ -211,7 +246,7 @@ // Make the location bar the first responder, if possible. - (void)focusLocationBar { - [tabStripController_ focusLocationBar]; + [toolbarController_ focusLocationBar]; } - (void)arrangeTabs { @@ -313,4 +348,5 @@ UpdateUIForContents(new_contents); #endif } + @end diff --git a/chrome/browser/cocoa/command_observer_bridge.h b/chrome/browser/cocoa/command_observer_bridge.h new file mode 100644 index 0000000..042c0d1 --- /dev/null +++ b/chrome/browser/cocoa/command_observer_bridge.h @@ -0,0 +1,41 @@ +// 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 <Cocoa/Cocoa.h> + +#include "chrome/browser/command_updater.h" + +@protocol CommandObserverProtocol; + +// A C++ bridge class that handles listening for updates to commands and +// passing them back to an object that supports the protocol delcared below. +// The observer will create one of these bridges, call ObserveCommand() on the +// command ids it cares about, and then wait for update notifications, +// delivered via -enabledStateChangedForCommand:enabled:. Destroying this +// bridge will handle automatically unregistering for updates, so there's no +// need to do that manually. + +class CommandObserverBridge : public CommandUpdater::CommandObserver { + public: + CommandObserverBridge(id<CommandObserverProtocol> observer, + CommandUpdater* commands); + virtual ~CommandObserverBridge(); + + // Register for updates about |command|. + void ObserveCommand(int command); + + protected: + // Overridden from CommandUpdater::CommandObserver + virtual void EnabledStateChangedForCommand(int command, bool enabled); + + private: + id<CommandObserverProtocol> observer_; // weak, owns me + CommandUpdater* commands_; // weak +}; + +// Implemented by the observing Objective-C object, called when there is a +// state change for the given command. +@protocol CommandObserverProtocol +- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled; +@end diff --git a/chrome/browser/cocoa/command_observer_bridge.mm b/chrome/browser/cocoa/command_observer_bridge.mm new file mode 100644 index 0000000..47ea888 --- /dev/null +++ b/chrome/browser/cocoa/command_observer_bridge.mm @@ -0,0 +1,26 @@ +// 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/command_observer_bridge.h" + +CommandObserverBridge::CommandObserverBridge( + id<CommandObserverProtocol> observer, CommandUpdater* commands) + : observer_(observer), commands_(commands) { + DCHECK(observer_ && commands_); +} + +CommandObserverBridge::~CommandObserverBridge() { + // Unregister the notifications + commands_->RemoveCommandObserver(this); +} + +void CommandObserverBridge::ObserveCommand(int command) { + commands_->AddCommandObserver(command, this); +} + +void CommandObserverBridge::EnabledStateChangedForCommand(int command, + bool enabled) { + [observer_ enabledStateChangedForCommand:command + enabled:enabled ? YES : NO]; +} diff --git a/chrome/browser/cocoa/tab_contents_controller.h b/chrome/browser/cocoa/tab_contents_controller.h index bf97dc3..ac8bd30 100644 --- a/chrome/browser/cocoa/tab_contents_controller.h +++ b/chrome/browser/cocoa/tab_contents_controller.h @@ -9,16 +9,12 @@ @class BookmarkView; @class GrowBoxView; -@class ToolbarView; class BookmarkModel; -class CommandUpdater; -class LocationBar; -class LocationBarViewMac; class TabContents; class TabContentsCommandObserver; class TabStripModel; -class ToolbarModel; +@class ToolbarView; // A class that controls the contents of a tab, including the toolbar and // web area. @@ -36,25 +32,14 @@ class ToolbarModel; @interface TabContentsController : NSViewController { @private - CommandUpdater* commands_; // weak, may be nil TabContentsCommandObserver* observer_; // nil if |commands_| is nil - LocationBarViewMac* locationBarView_; TabContents* contents_; // weak - ToolbarModel* toolbarModel_; // weak, one per window - IBOutlet ToolbarView* toolbarView_; - BookmarkModel* bookmarkModel_; // weak; one per window // TODO(jrg): write a BookmarkView IBOutlet ToolbarView* /* BookmarkView* */ bookmarkView_; - IBOutlet NSButton* backButton_; - IBOutlet NSButton* forwardButton_; - IBOutlet NSButton* reloadButton_; - IBOutlet NSButton* starButton_; - IBOutlet NSButton* goButton_; - IBOutlet NSTextField* locationBar_; IBOutlet NSBox* contentsBox_; IBOutlet GrowBoxView* growBox_; @@ -69,16 +54,11 @@ class ToolbarModel; - (id)initWithNibName:(NSString*)name bundle:(NSBundle*)bundle contents:(TabContents*)contents - commands:(CommandUpdater*)commands - toolbarModel:(ToolbarModel*)toolbarModel bookmarkModel:(BookmarkModel*)bookmarkModel; // Take this view (toolbar and web contents) full screen - (IBAction)fullScreen:(id)sender; -// Get the C++ bridge object representing the location bar for this tab. -- (LocationBar*)locationBar; - // Called when the tab contents is about to be put into the view hierarchy as // the selected tab. Handles things such as ensuring the toolbar is correctly // enabled. @@ -89,24 +69,10 @@ class ToolbarModel; // an entirely new tab contents object. - (void)tabDidChange:(TabContents*)updatedContents; -// Called when any url bar state changes. If |tabForRestoring| is non-NULL, -// it points to a TabContents whose state we should restore. -- (void)updateToolbarWithContents:(TabContents*)tabForRestoring; - -// Sets whether or not the current page in the frontmost tab is bookmarked. -- (void)setStarredState:(BOOL)isStarred; - // Return the rect, in WebKit coordinates (flipped), of the window's grow box // in the coordinate system of the content area of this tab. - (NSRect)growBoxRect; -// Called to update the loading state. Handles updating the go/stop button -// state. -- (void)setIsLoading:(BOOL)isLoading; - -// Make the location bar the first responder, if possible. -- (void)focusLocationBar; - // Change the visibility state of the bookmark bar. - (void)toggleBookmarkBar:(BOOL)enable; diff --git a/chrome/browser/cocoa/tab_contents_controller.mm b/chrome/browser/cocoa/tab_contents_controller.mm index 1ceb2a3..ce00782 100644 --- a/chrome/browser/cocoa/tab_contents_controller.mm +++ b/chrome/browser/cocoa/tab_contents_controller.mm @@ -5,56 +5,21 @@ #import "chrome/browser/cocoa/tab_contents_controller.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/bookmarks/bookmark_model.h" -#import "chrome/browser/cocoa/location_bar_view_mac.h" -#include "chrome/browser/command_updater.h" #include "chrome/browser/tab_contents/tab_contents.h" -#include "chrome/browser/toolbar_model.h" - -// Names of images in the bundle for the star icon (normal and 'starred'). -static NSString* const kStarImageName = @"star"; -static NSString* const kStarredImageName = @"starred"; - -@interface TabContentsController(CommandUpdates) -- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled; -@end @interface TabContentsController(Private) -- (void)updateToolbarCommandStatus; - (void)applyContentsBoxOffset:(BOOL)apply; @end -// A C++ bridge class that handles listening for updates to commands and -// passing them back to the controller. -class TabContentsCommandObserver : public CommandUpdater::CommandObserver { - public: - TabContentsCommandObserver(TabContentsController* controller, - CommandUpdater* commands); - ~TabContentsCommandObserver(); - - // Overridden from CommandUpdater::CommandObserver - void EnabledStateChangedForCommand(int command, bool enabled); - - private: - TabContentsController* controller_; // weak, owns me - CommandUpdater* commands_; // weak -}; - @implementation TabContentsController - (id)initWithNibName:(NSString*)name bundle:(NSBundle*)bundle contents:(TabContents*)contents - commands:(CommandUpdater*)commands - toolbarModel:(ToolbarModel*)toolbarModel bookmarkModel:(BookmarkModel*)bookmarkModel { if ((self = [super initWithNibName:name bundle:bundle])) { - commands_ = commands; - if (commands_) - observer_ = new TabContentsCommandObserver(self, commands); contents_ = contents; - toolbarModel_ = toolbarModel; bookmarkModel_ = bookmarkModel; } return self; @@ -63,27 +28,12 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver { - (void)dealloc { // make sure our contents have been removed from the window [[self view] removeFromSuperview]; - delete observer_; - delete locationBarView_; [super dealloc]; } - (void)awakeFromNib { [contentsBox_ setContentView:contents_->GetNativeView()]; [self applyContentsBoxOffset:YES]; - - // Provide a starting point since we won't get notifications if the state - // doesn't change between tabs. - [self updateToolbarCommandStatus]; - - locationBarView_ = new LocationBarViewMac(locationBar_); - locationBarView_->Init(); - - [locationBar_ setStringValue:@"http://dev.chromium.org"]; -} - -- (LocationBar*)locationBar { - return locationBarView_; } // Returns YES if the tab represented by this controller is the front-most. @@ -93,34 +43,6 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver { return [[self view] superview] ? YES : NO; } -// Called when the state for a command changes to |enabled|. Update the -// corresponding UI element. -- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled { - // We don't need to update anything if we're not the frontmost tab. - // TODO(pinkerton): i'm worried that observer ordering could cause the - // notification to be sent before we've been put into the view, but we - // appear to be called in the right order so far. - if (![self isCurrentTab]) - return; - - NSButton* button = nil; - switch (command) { - case IDC_BACK: - button = backButton_; - break; - case IDC_FORWARD: - button = forwardButton_; - break; - case IDC_HOME: - // TODO(pinkerton): add home button - break; - case IDC_STAR: - button = starButton_; - break; - } - [button setEnabled:enabled]; -} - - (IBAction)fullScreen:(id)sender { if ([[self view] isInFullScreenMode]) { [[self view] exitFullScreenModeWithOptions:nil]; @@ -129,21 +51,7 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver { } } -// Set the enabled state of the buttons on the toolbar to match the state in -// the controller. We can't only rely on notifications to do this because the -// command model only assumes a single toolbar and won't send notifications if -// the state doesn't change. -- (void)updateToolbarCommandStatus { - [backButton_ setEnabled:commands_->IsCommandEnabled(IDC_BACK) ? YES : NO]; - [forwardButton_ - setEnabled:commands_->IsCommandEnabled(IDC_FORWARD) ? YES : NO]; - [reloadButton_ - setEnabled:commands_->IsCommandEnabled(IDC_RELOAD) ? YES : NO]; - [starButton_ setEnabled:commands_->IsCommandEnabled(IDC_STAR) ? YES : NO]; -} - - (void)willBecomeSelectedTab { - [self updateToolbarCommandStatus]; } - (void)tabDidChange:(TabContents*)updatedContents { @@ -151,29 +59,6 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver { [contentsBox_ setContentView:contents_->GetNativeView()]; } -- (void)focusLocationBar { - if (locationBarView_) { - locationBarView_->FocusLocation(); - } -} - -- (void)updateToolbarWithContents:(TabContents*)tab { - // TODO(pinkerton): there's a lot of ui code in autocomplete_edit.cc - // that we'll want to duplicate. For now, just handle setting the text. - - // TODO(pinkerton): update the security lock icon and background color - - NSString* urlString = base::SysWideToNSString(toolbarModel_->GetText()); - [locationBar_ setStringValue:urlString]; -} - -- (void)setStarredState:(BOOL)isStarred { - NSString* starImageName = kStarImageName; - if (isStarred) - starImageName = kStarredImageName; - [starButton_ setImage:[NSImage imageNamed:starImageName]]; -} - // Return the rect, in WebKit coordinates (flipped), of the window's grow box // in the coordinate system of the content area of this tab. - (NSRect)growBoxRect { @@ -199,13 +84,6 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver { return localGrowBox; } -- (void)setIsLoading:(BOOL)isLoading { - NSString* imageName = @"go"; - if (isLoading) - imageName = @"stop"; - [goButton_ setImage:[NSImage imageNamed:imageName]]; -} - - (void)toggleBookmarkBar:(BOOL)enable { contentsBoxHasOffset_ = enable; [self applyContentsBoxOffset:enable]; @@ -248,28 +126,3 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver { } @end - -//-------------------------------------------------------------------------- - -TabContentsCommandObserver::TabContentsCommandObserver( - TabContentsController* controller, CommandUpdater* commands) - : controller_(controller), commands_(commands) { - DCHECK(controller_ && commands); - // Register for notifications about state changes for the toolbar buttons - commands_->AddCommandObserver(IDC_BACK, this); - commands_->AddCommandObserver(IDC_FORWARD, this); - commands_->AddCommandObserver(IDC_RELOAD, this); - commands_->AddCommandObserver(IDC_HOME, this); - commands_->AddCommandObserver(IDC_STAR, this); -} - -TabContentsCommandObserver::~TabContentsCommandObserver() { - // Unregister the notifications - commands_->RemoveCommandObserver(this); -} - -void TabContentsCommandObserver::EnabledStateChangedForCommand(int command, - bool enabled) { - [controller_ enabledStateChangedForCommand:command - enabled:enabled ? YES : NO]; -} diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h index 7159d8d..ab6b902 100644 --- a/chrome/browser/cocoa/tab_strip_controller.h +++ b/chrome/browser/cocoa/tab_strip_controller.h @@ -36,10 +36,10 @@ class ToolbarModel; @private TabContents* currentTab_; // weak, tab for which we're showing state TabStripView* tabView_; // weak + NSView* switchView_; // weak NSButton* newTabButton_; // weak, obtained from the nib. TabStripModelObserverBridge* bridge_; TabStripModel* tabModel_; // weak - ToolbarModel* toolbarModel_; // weak, one per browser BookmarkModel* bookmarkModel_; // weak, one per profile (= one per Browser*) CommandUpdater* commands_; // weak, may be nil // access to the TabContentsControllers (which own the parent view @@ -56,33 +56,18 @@ class ToolbarModel; } // Initialize the controller with a view and browser that contains -// everything else we'll need. +// everything else we'll need. |switchView| is the view whose contents get +// "switched" every time the user switches tabs. The children of this view +// will be released, so if you want them to stay around, make sure +// you have retained them. - (id)initWithView:(TabStripView*)view + switchView:(NSView*)switchView browser:(Browser*)browser; -// Get the C++ bridge object representing the location bar for the current tab. -- (LocationBar*)locationBar; - -// Updates the toolbar (and transitively the location bar) with the states of -// the specified |tab|. If |shouldRestore| is true, we're switching -// (back?) to this tab and should restore any previous location bar state -// (such as user editing) as well. -- (void)updateToolbarWithContents:(TabContents*)tab - shouldRestoreState:(BOOL)shouldRestore; - -// Sets whether or not the current page in the frontmost tab is bookmarked. -- (void)setStarredState:(BOOL)isStarred; - // Return the rect, in WebKit coordinates (flipped), of the window's grow box // in the coordinate system of the content area of the currently selected tab. - (NSRect)selectedTabGrowBoxRect; -// Called to tell the selected tab to update its loading state. -- (void)setIsLoading:(BOOL)isLoading; - -// Make the location bar the first responder, if possible. -- (void)focusLocationBar; - // Return a boolean (ObjC BOOL, not C++ bool) to say if the bookmark // bar is visible. - (BOOL)isBookmarkBarVisible; diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm index 6e3e70b..e4d669a 100644 --- a/chrome/browser/cocoa/tab_strip_controller.mm +++ b/chrome/browser/cocoa/tab_strip_controller.mm @@ -20,12 +20,13 @@ @implementation TabStripController - (id)initWithView:(TabStripView*)view + switchView:(NSView*)switchView browser:(Browser*)browser { - DCHECK(view && browser); + DCHECK(view && switchView && browser); if ((self = [super init])) { tabView_ = view; + switchView_ = switchView; tabModel_ = browser->tabstrip_model(); - toolbarModel_ = browser->toolbar_model(); bookmarkModel_ = browser->profile()->GetBookmarkModel(); commands_ = browser->command_updater(); bridge_ = new TabStripModelObserverBridge(tabModel_, self); @@ -62,22 +63,20 @@ TabContentsController* controller = [tabContentsArray_ objectAtIndex:index]; // 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; + NSRect frame = [switchView_ bounds]; [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. There + // child of |switchView_| because we're the one who put it there. There // may not be any children in the case of a tab that's been closed, in // which case there's no swapping going on. - NSArray* subviews = [contentView subviews]; + NSArray* subviews = [switchView_ subviews]; if ([subviews count]) { NSView* oldView = [subviews objectAtIndex:0]; - [contentView replaceSubview:oldView with:newView]; + [switchView_ replaceSubview:oldView with:newView]; } else { - [contentView addSubview:newView]; + [switchView_ addSubview:newView]; } } @@ -224,8 +223,6 @@ [[[TabContentsController alloc] initWithNibName:@"TabContents" bundle:nil contents:contents - commands:commands_ - toolbarModel:toolbarModel_ bookmarkModel:bookmarkModel_] autorelease]; if ([self isBookmarkBarVisible]) @@ -315,32 +312,6 @@ [updatedController tabDidChange:contents]; } -- (LocationBar*)locationBar { - TabContentsController* selectedController = - [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; - return [selectedController locationBar]; -} - -- (void)updateToolbarWithContents:(TabContents*)tab - shouldRestoreState:(BOOL)shouldRestore { - // TODO(pinkerton): OS_WIN maintains this, but I'm not sure why. It's - // available by querying the model, which we have available to us. - currentTab_ = tab; - - // tell the appropriate controller to update its state. |shouldRestore| being - // YES means we're going back to this tab and should put back any state - // associated with it. - TabContentsController* controller = - [tabContentsArray_ objectAtIndex:tabModel_->GetIndexOfTabContents(tab)]; - [controller updateToolbarWithContents:shouldRestore ? tab : nil]; -} - -- (void)setStarredState:(BOOL)isStarred { - TabContentsController* selectedController = - [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; - [selectedController setStarredState:isStarred]; -} - // Return the rect, in WebKit coordinates (flipped), of the window's grow box // in the coordinate system of the content area of the currently selected tab. - (NSRect)selectedTabGrowBoxRect { @@ -358,23 +329,6 @@ return [selectedController growBoxRect]; } -// Called to tell the selected tab to update its loading state. -- (void)setIsLoading:(BOOL)isLoading { - // TODO(pinkerton): update the favicon on the selected tab view to/from - // a spinner? - - TabContentsController* selectedController = - [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; - [selectedController setIsLoading:isLoading]; -} - -// Make the location bar the first responder, if possible. -- (void)focusLocationBar { - TabContentsController* selectedController = - [tabContentsArray_ objectAtIndex:tabModel_->selected_index()]; - [selectedController focusLocationBar]; -} - - (BOOL)isBookmarkBarVisible { return [bookmarkBarStateController_ visible]; } @@ -386,7 +340,6 @@ for (TabContentsController *controller in tabContentsArray_) { [controller toggleBookmarkBar:visible]; } - } @end diff --git a/chrome/browser/cocoa/tab_window_controller.h b/chrome/browser/cocoa/tab_window_controller.h index f0fcb524..43df6f2 100644 --- a/chrome/browser/cocoa/tab_window_controller.h +++ b/chrome/browser/cocoa/tab_window_controller.h @@ -11,6 +11,12 @@ // know anything about the actual tab implementation or model, as that is fairly // application-specific. It only provides an API to be overridden by subclasses // to fill in the details. +// +// This assumes that there will be a view in the nib, connected to +// |tabContentArea_|, that indicates the content that it switched when switching +// between tabs. It needs to be a regular NSView, not something like an NSBox +// because the TabStripController makes certain assumptions about how it can +// swap out subviews. #import <Cocoa/Cocoa.h> @@ -19,9 +25,7 @@ @interface TabWindowController : NSWindowController { @private - IBOutlet NSBox* contentBox_; // Only valid at window creation time, used - // to position the tab strip. nil afterwards. - // TODO(pinkerton): get rid of this. + IBOutlet NSView* tabContentArea_; IBOutlet TabStripView* tabStripView_; NSWindow* overlayWindow_; // Used during dragging for window opacity tricks NSView* cachedContentView_; // Used during dragging for identifying which @@ -29,6 +33,7 @@ // (weak) } @property(readonly, nonatomic) TabStripView* tabStripView; +@property(readonly, nonatomic) NSView* tabContentArea; // Used during tab dragging to turn on/off the overlay window when a tab // is torn off. @@ -62,4 +67,11 @@ @end +@interface TabWindowController(ProtectedMethods) +// A list of all the views that need to move to the overlay window. Subclasses +// can override this to add more things besides the tab strip. Be sure to +// call the superclass' version if overridden. +- (NSArray*)viewsToMoveToOverlay; +@end + #endif // CHROME_BROWSER_TAB_WINDOW_CONTROLLER_H_ diff --git a/chrome/browser/cocoa/tab_window_controller.mm b/chrome/browser/cocoa/tab_window_controller.mm index 691095f..456c973 100644 --- a/chrome/browser/cocoa/tab_window_controller.mm +++ b/chrome/browser/cocoa/tab_window_controller.mm @@ -13,19 +13,16 @@ @implementation TabWindowController @synthesize tabStripView = tabStripView_; +@synthesize tabContentArea = tabContentArea_; - (void)windowDidLoad { // 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]; + NSRect tabFrame = [tabContentArea_ frame]; tabFrame.origin = NSMakePoint(0, NSMaxY(tabFrame)); tabFrame.size.height = NSHeight([tabStripView_ frame]); [tabStripView_ setFrame:tabFrame]; [[[[self window] contentView] superview] addSubview:tabStripView_]; - - // tab switching will destroy the content area, so nil this out to ensure - // that nobody tries to use it. - contentBox_ = nil; } - (void)removeOverlay { @@ -45,6 +42,21 @@ [self setUseOverlay:YES]; } +- (NSArray*)viewsToMoveToOverlay { + return [NSArray arrayWithObject:[self tabStripView]]; +} + +// if |useOverlay| is true, we're moving views into the overlay's content +// area. If false, we're moving out of the overlay back into the window's +// content. +- (void)moveViewsBetweenWindowAndOverlay:(BOOL)useOverlay { + NSView* moveTo = useOverlay ? + [overlayWindow_ contentView] : [cachedContentView_ superview]; + NSArray* viewsToMove = [self viewsToMoveToOverlay]; + for (NSView* view in viewsToMove) + [moveTo addSubview:view]; +} + // If |useOverlay| is YES, creates a new overlay window and puts the tab strip // and the content area inside of it. This allows it to have a different opacity // from the title bar. If NO, returns everything to the previous state and @@ -66,7 +78,7 @@ NSView *contentView = [overlayWindow_ contentView]; [contentView addSubview:[self tabStripView]]; cachedContentView_ = [[self window] contentView]; - [contentView addSubview:cachedContentView_]; + [self moveViewsBetweenWindowAndOverlay:useOverlay]; [overlayWindow_ setHasShadow:YES]; [[self window] addChildWindow:overlayWindow_ ordered:NSWindowAbove]; [overlayWindow_ orderFront:nil]; @@ -75,7 +87,7 @@ DCHECK(cachedContentView_); [[self window] setHasShadow:YES]; [[self window] setContentView:cachedContentView_]; - [[cachedContentView_ superview] addSubview:[self tabStripView]]; + [self moveViewsBetweenWindowAndOverlay:useOverlay]; [[self window] makeFirstResponder:cachedContentView_]; [[self window] display]; [[self window] removeChildWindow:overlayWindow_]; diff --git a/chrome/browser/cocoa/toolbar_controller.h b/chrome/browser/cocoa/toolbar_controller.h new file mode 100644 index 0000000..d2cc2c4 --- /dev/null +++ b/chrome/browser/cocoa/toolbar_controller.h @@ -0,0 +1,60 @@ +// 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_TOOLBAR_CONTROLLER_H_ +#define CHROME_BROWSER_COCOA_TOOLBAR_CONTROLLER_H_ + +#import <Cocoa/Cocoa.h> + +#import "chrome/browser/cocoa/command_observer_bridge.h" + +class CommandUpdater; +class LocationBar; +class LocationBarViewMac; +class TabContents; +class ToolbarModel; +class ToolbarView; + +// A controller for the toolbar in the browser window. Manages updating the +// state for location bar and back/fwd/reload/go buttons. + +@interface ToolbarController : NSViewController<CommandObserverProtocol> { + @private + ToolbarModel* toolbarModel_; // weak, one per window + CommandUpdater* commands_; // weak, one per window + CommandObserverBridge* commandObserver_; + LocationBarViewMac* locationBarView_; + + IBOutlet NSButton* backButton_; + IBOutlet NSButton* forwardButton_; + IBOutlet NSButton* reloadButton_; + IBOutlet NSButton* starButton_; + IBOutlet NSButton* goButton_; + IBOutlet NSTextField* locationBar_; +} + +// Initialize the toolbar and register for command updates. +- (id)initWithModel:(ToolbarModel*)model + commands:(CommandUpdater*)commands; + +// Get the C++ bridge object representing the location bar for this tab. +- (LocationBar*)locationBar; + +// Make the location bar the first responder, if possible. +- (void)focusLocationBar; + +// Called when any url bar state changes. If |tabForRestoring| is non-NULL, +// it points to a TabContents whose state we should restore. +- (void)updateToolbarWithContents:(TabContents*)tabForRestoring; + +// Sets whether or not the current page in the frontmost tab is bookmarked. +- (void)setStarredState:(BOOL)isStarred; + +// Called to update the loading state. Handles updating the go/stop button +// state. +- (void)setIsLoading:(BOOL)isLoading; + +@end + +#endif // CHROME_BROWSER_COCOA_TOOLBAR_CONTROLLER_H_ diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm new file mode 100644 index 0000000..e77c30c --- /dev/null +++ b/chrome/browser/cocoa/toolbar_controller.mm @@ -0,0 +1,123 @@ +// 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/toolbar_controller.h" + +#include "base/sys_string_conversions.h" +#include "chrome/app/chrome_dll_resource.h" +#import "chrome/browser/cocoa/location_bar_view_mac.h" +#include "chrome/browser/toolbar_model.h" + +// Names of images in the bundle for the star icon (normal and 'starred'). +static NSString* const kStarImageName = @"star"; +static NSString* const kStarredImageName = @"starred"; + +@interface ToolbarController(Private) +- (void)initCommandStatus:(CommandUpdater*)commands; +@end + +@implementation ToolbarController + +- (id)initWithModel:(ToolbarModel*)model + commands:(CommandUpdater*)commands { + DCHECK(model && commands); + if ((self = [super initWithNibName:@"Toolbar" bundle:nil])) { + toolbarModel_ = model; + commands_ = commands; + + // Register for notifications about state changes for the toolbar buttons + commandObserver_ = new CommandObserverBridge(self, commands); + commandObserver_->ObserveCommand(IDC_BACK); + commandObserver_->ObserveCommand(IDC_FORWARD); + commandObserver_->ObserveCommand(IDC_RELOAD); + commandObserver_->ObserveCommand(IDC_HOME); + commandObserver_->ObserveCommand(IDC_STAR); + } + return self; +} + +// Called after the view is done loading and the outlets have been hooked up. +// Now we can hook up bridges that rely on UI objects such as the location +// bar and button state. +- (void)awakeFromNib { + [self initCommandStatus:commands_]; + locationBarView_ = new LocationBarViewMac(locationBar_); + locationBarView_->Init(); + [locationBar_ setStringValue:@"http://dev.chromium.org"]; +} + +- (void)dealloc { + delete locationBarView_; + delete commandObserver_; + [super dealloc]; +} + +- (LocationBar*)locationBar { + return locationBarView_; +} + +- (void)focusLocationBar { + if (locationBarView_) { + locationBarView_->FocusLocation(); + } +} + +// Called when the state for a command changes to |enabled|. Update the +// corresponding UI element. +- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled { + NSButton* button = nil; + switch (command) { + case IDC_BACK: + button = backButton_; + break; + case IDC_FORWARD: + button = forwardButton_; + break; + case IDC_HOME: + // TODO(pinkerton): add home button + break; + case IDC_STAR: + button = starButton_; + break; + } + [button setEnabled:enabled]; +} + +// Init the enabled state of the buttons on the toolbar to match the state in +// the controller. +- (void)initCommandStatus:(CommandUpdater*)commands { + [backButton_ setEnabled:commands->IsCommandEnabled(IDC_BACK) ? YES : NO]; + [forwardButton_ + setEnabled:commands->IsCommandEnabled(IDC_FORWARD) ? YES : NO]; + [reloadButton_ + setEnabled:commands->IsCommandEnabled(IDC_RELOAD) ? YES : NO]; + // TODO(pinkerton): Add home button. + [starButton_ setEnabled:commands->IsCommandEnabled(IDC_STAR) ? YES : NO]; +} + +- (void)updateToolbarWithContents:(TabContents*)tab { + // TODO(pinkerton): there's a lot of ui code in autocomplete_edit.cc + // that we'll want to duplicate. For now, just handle setting the text. + + // TODO(pinkerton): update the security lock icon and background color + + NSString* urlString = base::SysWideToNSString(toolbarModel_->GetText()); + [locationBar_ setStringValue:urlString]; +} + +- (void)setStarredState:(BOOL)isStarred { + NSString* starImageName = kStarImageName; + if (isStarred) + starImageName = kStarredImageName; + [starButton_ setImage:[NSImage imageNamed:starImageName]]; +} + +- (void)setIsLoading:(BOOL)isLoading { + NSString* imageName = @"go"; + if (isLoading) + imageName = @"stop"; + [goButton_ setImage:[NSImage imageNamed:imageName]]; +} + +@end |